Skip to content

Commit beb18e6

Browse files
authored
merge main into amd-staging (llvm#3052)
2 parents 9f953b6 + cfd0fa7 commit beb18e6

File tree

171 files changed

+72601
-4667
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+72601
-4667
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,9 +1554,9 @@ the configuration (without a prefix: ``Auto``).
15541554

15551555
.. code-block:: c++
15561556

1557-
#define A \
1558-
int aaaa; \
1559-
int b; \
1557+
#define A \
1558+
int aaaa; \
1559+
int b; \
15601560
int dddddddddd;
15611561

15621562

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===- LifetimeSafety.h - C++ Lifetime Safety Analysis -*----------- C++-*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the entry point for a dataflow-based static analysis
10+
// that checks for C++ lifetime violations.
11+
//
12+
// The analysis is based on the concepts of "origins" and "loans" to track
13+
// pointer lifetimes and detect issues like use-after-free and dangling
14+
// pointers. See the RFC for more details:
15+
// https://discourse.llvm.org/t/rfc-intra-procedural-lifetime-analysis-in-clang/86291
16+
//
17+
//===----------------------------------------------------------------------===//
18+
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
19+
#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
20+
#include "clang/AST/DeclBase.h"
21+
#include "clang/Analysis/AnalysisDeclContext.h"
22+
#include "clang/Analysis/CFG.h"
23+
namespace clang {
24+
25+
void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
26+
AnalysisDeclContext &AC);
27+
28+
} // namespace clang
29+
30+
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H

clang/include/clang/Analysis/Analyses/UninitializedValues.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class UninitUse {
4747
/// Does this use always see an uninitialized value?
4848
bool AlwaysUninit;
4949

50+
/// Is this use a const reference to this variable?
51+
bool ConstRefUse = false;
52+
5053
/// This use is always uninitialized if it occurs after any of these branches
5154
/// is taken.
5255
SmallVector<Branch, 2> UninitBranches;
@@ -61,10 +64,13 @@ class UninitUse {
6164

6265
void setUninitAfterCall() { UninitAfterCall = true; }
6366
void setUninitAfterDecl() { UninitAfterDecl = true; }
67+
void setConstRefUse() { ConstRefUse = true; }
6468

6569
/// Get the expression containing the uninitialized use.
6670
const Expr *getUser() const { return User; }
6771

72+
bool isConstRefUse() const { return ConstRefUse; }
73+
6874
/// The kind of uninitialized use.
6975
enum Kind {
7076
/// The use might be uninitialized.
@@ -110,10 +116,6 @@ class UninitVariablesHandler {
110116
virtual void handleUseOfUninitVariable(const VarDecl *vd,
111117
const UninitUse &use) {}
112118

113-
/// Called when the uninitialized variable is used as const refernce argument.
114-
virtual void handleConstRefUseOfUninitVariable(const VarDecl *vd,
115-
const UninitUse &use) {}
116-
117119
/// Called when the uninitialized variable analysis detects the
118120
/// idiom 'int x = x'. All other uses of 'x' within the initializer
119121
/// are handled by handleUseOfUninitVariable.

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
532532
DanglingInitializerList,
533533
DanglingGsl,
534534
ReturnStackAddress]>;
535+
536+
def LifetimeSafety : DiagGroup<"experimental-lifetime-safety">;
537+
535538
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
536539
def DllexportExplicitInstantiationDecl : DiagGroup<"dllexport-explicit-instantiation-decl">;
537540
def ExcessInitializers : DiagGroup<"excess-initializers">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10627,6 +10627,10 @@ def warn_dangling_reference_captured_by_unknown : Warning<
1062710627
"object whose reference is captured will be destroyed at the end of "
1062810628
"the full-expression">, InGroup<DanglingCapture>;
1062910629

10630+
def warn_experimental_lifetime_safety_dummy_warning : Warning<
10631+
"todo: remove this warning after we have atleast one warning based on the lifetime analysis">,
10632+
InGroup<LifetimeSafety>, DefaultIgnore;
10633+
1063010634
// For non-floating point, expressions of the form x == x or x != x
1063110635
// should result in a warning, since these always evaluate to a constant.
1063210636
// Array comparisons have similar warnings

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,94 @@ def GetGlobalOp : CIR_Op<"get_global",
16691669
}];
16701670
}
16711671

1672+
//===----------------------------------------------------------------------===//
1673+
// SetBitfieldOp
1674+
//===----------------------------------------------------------------------===//
1675+
1676+
def SetBitfieldOp : CIR_Op<"set_bitfield"> {
1677+
let summary = "Set the value of a bitfield member";
1678+
let description = [{
1679+
The `cir.set_bitfield` operation provides a store-like access to
1680+
a bit field of a record.
1681+
1682+
A bitfield info attribute must be provided to describe the location of
1683+
the bitfield within the memory referenced by the $addr argument.
1684+
The $src argument is inserted at the appropriate place in the memory and
1685+
the value that was stored. Returns the value being stored.
1686+
1687+
A unit attribute `volatile` can be used to indicate a volatile store of the
1688+
bitfield.
1689+
```mlir
1690+
cir.set_bitfield(#bfi, %0 : !cir.ptr<!u32i>, %1 : !s32i) {is_volatile}
1691+
-> !s32i
1692+
```
1693+
1694+
Example.
1695+
Suppose we have a struct with multiple bitfields stored in
1696+
different storages. The `cir.set_bitfield` operation sets the value
1697+
of the bitfield.
1698+
```C++
1699+
typedef struct {
1700+
int a : 4;
1701+
int b : 27;
1702+
int c : 17;
1703+
int d : 2;
1704+
int e : 15;
1705+
} S;
1706+
1707+
void store_bitfield(S& s) {
1708+
s.e = 3;
1709+
}
1710+
```
1711+
1712+
```mlir
1713+
// 'e' is in the storage with the index 1
1714+
!record_type = !cir.record<struct "S" packed padded {!u64i, !u16i,
1715+
!cir.array<!u8i x 2>} #cir.record.decl.ast>
1716+
#bfi_e = #cir.bitfield_info<name = "e", storage_type = !u16i, size = 15,
1717+
offset = 0, is_signed = true>
1718+
1719+
%1 = cir.const #cir.int<3> : !s32i
1720+
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type>
1721+
%3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type>
1722+
-> !cir.ptr<!u16i>
1723+
%4 = cir.set_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) -> !s32i
1724+
```
1725+
}];
1726+
1727+
let arguments = (ins
1728+
Arg<CIR_PointerType, "the address to store the value", [MemWrite]>:$addr,
1729+
CIR_AnyType:$src,
1730+
BitfieldInfoAttr:$bitfield_info,
1731+
UnitAttr:$is_volatile
1732+
);
1733+
1734+
let results = (outs CIR_IntType:$result);
1735+
1736+
let assemblyFormat = [{ `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,`
1737+
$src`:`type($src) `)` attr-dict `->` type($result) }];
1738+
1739+
let builders = [
1740+
OpBuilder<(ins "mlir::Type":$type,
1741+
"mlir::Value":$addr,
1742+
"mlir::Type":$storage_type,
1743+
"mlir::Value":$src,
1744+
"llvm::StringRef":$name,
1745+
"unsigned":$size,
1746+
"unsigned":$offset,
1747+
"bool":$is_signed,
1748+
"bool":$is_volatile
1749+
),
1750+
[{
1751+
BitfieldInfoAttr info =
1752+
BitfieldInfoAttr::get($_builder.getContext(),
1753+
name, storage_type,
1754+
size, offset, is_signed);
1755+
build($_builder, $_state, type, addr, src, info, is_volatile);
1756+
}]>
1757+
];
1758+
}
1759+
16721760
//===----------------------------------------------------------------------===//
16731761
// GetBitfieldOp
16741762
//===----------------------------------------------------------------------===//
@@ -1685,6 +1773,9 @@ def GetBitfieldOp : CIR_Op<"get_bitfield"> {
16851773

16861774
A unit attribute `volatile` can be used to indicate a volatile load of the
16871775
bitfield.
1776+
```mlir
1777+
cir.get_bitfield(#bfi, %0 {is_volatile} : !cir.ptr<!u64i>) -> !s32i
1778+
```
16881779

16891780
Example:
16901781
Suppose we have a struct with multiple bitfields stored in

clang/include/clang/Format/Format.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,9 @@ struct FormatStyle {
513513
ENAS_LeftWithLastLine,
514514
/// Align escaped newlines in the right-most column.
515515
/// \code
516-
/// #define A \
517-
/// int aaaa; \
518-
/// int b; \
516+
/// #define A \
517+
/// int aaaa; \
518+
/// int b; \
519519
/// int dddddddddd;
520520
/// \endcode
521521
ENAS_Right,

clang/lib/Analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_clang_library(clangAnalysis
2121
FixitUtil.cpp
2222
IntervalPartition.cpp
2323
IssueHash.cpp
24+
LifetimeSafety.cpp
2425
LiveVariables.cpp
2526
MacroExpansionContext.cpp
2627
ObjCNoReturn.cpp

0 commit comments

Comments
 (0)