Skip to content

Commit 5c145b7

Browse files
committed
merge main into amd-staging
Change-Id: I5b10a89cbc7e5a92281279f2ab871ad2de2054b5
2 parents f4fe12d + 9ebe8b9 commit 5c145b7

File tree

290 files changed

+9139
-3764
lines changed

Some content is hidden

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

290 files changed

+9139
-3764
lines changed

.github/workflows/libcxx-build-and-test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ jobs:
146146
'generic-no-experimental',
147147
'generic-no-filesystem',
148148
'generic-no-localization',
149+
'generic-no-terminal',
149150
'generic-no-random_device',
150151
'generic-no-threads',
151152
'generic-no-tzdb',

clang/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ Bug Fixes to C++ Support
295295
- Clang now properly handles the order of attributes in `extern` blocks. (#GH101990).
296296
- Fixed an assertion failure by preventing null explicit object arguments from being deduced. (#GH102025).
297297
- Correctly check constraints of explicit instantiations of member functions. (#GH46029)
298+
- Fixed an assertion failure about a constraint of a friend function template references to a value with greater
299+
template depth than the friend function template. (#GH98258)
298300

299301
Bug Fixes to AST Handling
300302
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -313,6 +315,12 @@ Miscellaneous Clang Crashes Fixed
313315
- Fixed a crash caused by long chains of ``sizeof`` and other similar operators
314316
that can be followed by a non-parenthesized expression. (#GH45061)
315317

318+
- Fixed an crash when compiling ``#pragma STDC FP_CONTRACT DEFAULT`` with
319+
``-ffp-contract=fast-honor-pragmas``. (#GH104830)
320+
321+
- Fixed a crash when function has more than 65536 parameters.
322+
Now a diagnostic is emitted. (#GH35741)
323+
316324
OpenACC Specific Changes
317325
------------------------
318326

clang/include/clang/AST/Type.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1929,6 +1929,11 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
19291929
unsigned Kind : NumOfBuiltinTypeBits;
19301930
};
19311931

1932+
public:
1933+
static constexpr int FunctionTypeNumParamsWidth = 16;
1934+
static constexpr int FunctionTypeNumParamsLimit = (1 << 16) - 1;
1935+
1936+
protected:
19321937
/// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
19331938
/// Only common bits are stored here. Additional uncommon bits are stored
19341939
/// in a trailing object after FunctionProtoType.
@@ -1966,7 +1971,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
19661971
/// According to [implimits] 8 bits should be enough here but this is
19671972
/// somewhat easy to exceed with metaprogramming and so we would like to
19681973
/// keep NumParams as wide as reasonably possible.
1969-
unsigned NumParams : 16;
1974+
unsigned NumParams : FunctionTypeNumParamsWidth;
19701975

19711976
/// The type of exception specification this function has.
19721977
LLVM_PREFERRED_TYPE(ExceptionSpecificationType)

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ def ext_decomp_decl_empty : ExtWarn<
481481
"ISO C++17 does not allow a decomposition group to be empty">,
482482
InGroup<DiagGroup<"empty-decomposition">>;
483483

484+
def err_function_parameter_limit_exceeded : Error<
485+
"too many function parameters; subsequent parameters will be ignored">;
486+
484487
// C++26 structured bindings
485488
def ext_decl_attrs_on_binding : ExtWarn<
486489
"an attribute specifier sequence attached to a structured binding declaration "

clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ ANALYZER_OPTION(
407407
ANALYZER_OPTION(unsigned, MaxSymbolComplexity, "max-symbol-complexity",
408408
"The maximum complexity of symbolic constraint.", 35)
409409

410+
// HACK:https://discourse.llvm.org/t/rfc-make-istainted-and-complex-symbols-friends/79570
411+
// Ideally, we should get rid of this option soon.
412+
ANALYZER_OPTION(unsigned, MaxTaintedSymbolComplexity, "max-tainted-symbol-complexity",
413+
"[DEPRECATED] The maximum complexity of a symbol to carry taint", 9)
414+
410415
ANALYZER_OPTION(unsigned, MaxTimesInlineLarge, "max-times-inline-large",
411416
"The maximum times a large function could be inlined.", 32)
412417

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ class SPIRVABIInfo : public CommonSPIRABIInfo {
3232
void computeInfo(CGFunctionInfo &FI) const override;
3333

3434
private:
35+
ABIArgInfo classifyReturnType(QualType RetTy) const;
3536
ABIArgInfo classifyKernelArgumentType(QualType Ty) const;
37+
ABIArgInfo classifyArgumentType(QualType Ty) const;
3638
};
3739
} // end anonymous namespace
3840
namespace {
@@ -64,6 +66,27 @@ void CommonSPIRABIInfo::setCCs() {
6466
RuntimeCC = llvm::CallingConv::SPIR_FUNC;
6567
}
6668

69+
ABIArgInfo SPIRVABIInfo::classifyReturnType(QualType RetTy) const {
70+
if (getTarget().getTriple().getVendor() != llvm::Triple::AMD)
71+
return DefaultABIInfo::classifyReturnType(RetTy);
72+
if (!isAggregateTypeForABI(RetTy) || getRecordArgABI(RetTy, getCXXABI()))
73+
return DefaultABIInfo::classifyReturnType(RetTy);
74+
75+
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
76+
const RecordDecl *RD = RT->getDecl();
77+
if (RD->hasFlexibleArrayMember())
78+
return DefaultABIInfo::classifyReturnType(RetTy);
79+
}
80+
81+
// TODO: The AMDGPU ABI is non-trivial to represent in SPIR-V; in order to
82+
// avoid encoding various architecture specific bits here we return everything
83+
// as direct to retain type info for things like aggregates, for later perusal
84+
// when translating back to LLVM/lowering in the BE. This is also why we
85+
// disable flattening as the outcomes can mismatch between SPIR-V and AMDGPU.
86+
// This will be revisited / optimised in the future.
87+
return ABIArgInfo::getDirect(CGT.ConvertType(RetTy), 0u, nullptr, false);
88+
}
89+
6790
ABIArgInfo SPIRVABIInfo::classifyKernelArgumentType(QualType Ty) const {
6891
if (getContext().getLangOpts().CUDAIsDevice) {
6992
// Coerce pointer arguments with default address space to CrossWorkGroup
@@ -78,18 +101,51 @@ ABIArgInfo SPIRVABIInfo::classifyKernelArgumentType(QualType Ty) const {
78101
return ABIArgInfo::getDirect(LTy, 0, nullptr, false);
79102
}
80103

81-
// Force copying aggregate type in kernel arguments by value when
82-
// compiling CUDA targeting SPIR-V. This is required for the object
83-
// copied to be valid on the device.
84-
// This behavior follows the CUDA spec
85-
// https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-function-argument-processing,
86-
// and matches the NVPTX implementation.
87-
if (isAggregateTypeForABI(Ty))
104+
if (isAggregateTypeForABI(Ty)) {
105+
if (getTarget().getTriple().getVendor() == llvm::Triple::AMD)
106+
// TODO: The AMDGPU kernel ABI passes aggregates byref, which is not
107+
// currently expressible in SPIR-V; SPIR-V passes aggregates byval,
108+
// which the AMDGPU kernel ABI does not allow. Passing aggregates as
109+
// direct works around this impedance mismatch, as it retains type info
110+
// and can be correctly handled, post reverse-translation, by the AMDGPU
111+
// BE, which has to support this CC for legacy OpenCL purposes. It can
112+
// be brittle and does lead to performance degradation in certain
113+
// pathological cases. This will be revisited / optimised in the future,
114+
// once a way to deal with the byref/byval impedance mismatch is
115+
// identified.
116+
return ABIArgInfo::getDirect(LTy, 0, nullptr, false);
117+
// Force copying aggregate type in kernel arguments by value when
118+
// compiling CUDA targeting SPIR-V. This is required for the object
119+
// copied to be valid on the device.
120+
// This behavior follows the CUDA spec
121+
// https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#global-function-argument-processing,
122+
// and matches the NVPTX implementation.
88123
return getNaturalAlignIndirect(Ty, /* byval */ true);
124+
}
89125
}
90126
return classifyArgumentType(Ty);
91127
}
92128

129+
ABIArgInfo SPIRVABIInfo::classifyArgumentType(QualType Ty) const {
130+
if (getTarget().getTriple().getVendor() != llvm::Triple::AMD)
131+
return DefaultABIInfo::classifyArgumentType(Ty);
132+
if (!isAggregateTypeForABI(Ty))
133+
return DefaultABIInfo::classifyArgumentType(Ty);
134+
135+
// Records with non-trivial destructors/copy-constructors should not be
136+
// passed by value.
137+
if (auto RAA = getRecordArgABI(Ty, getCXXABI()))
138+
return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
139+
140+
if (const RecordType *RT = Ty->getAs<RecordType>()) {
141+
const RecordDecl *RD = RT->getDecl();
142+
if (RD->hasFlexibleArrayMember())
143+
return DefaultABIInfo::classifyArgumentType(Ty);
144+
}
145+
146+
return ABIArgInfo::getDirect(CGT.ConvertType(Ty), 0u, nullptr, false);
147+
}
148+
93149
void SPIRVABIInfo::computeInfo(CGFunctionInfo &FI) const {
94150
// The logic is same as in DefaultABIInfo with an exception on the kernel
95151
// arguments handling.

clang/lib/Parse/ParseDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8025,6 +8025,17 @@ void Parser::ParseParameterDeclarationClause(
80258025
// Consume the keyword.
80268026
ConsumeToken();
80278027
}
8028+
8029+
// We can only store so many parameters
8030+
// Skip until the the end of the parameter list, ignoring
8031+
// parameters that would overflow.
8032+
if (ParamInfo.size() == Type::FunctionTypeNumParamsLimit) {
8033+
Diag(ParmDeclarator.getBeginLoc(),
8034+
diag::err_function_parameter_limit_exceeded);
8035+
SkipUntil(tok::r_paren, SkipUntilFlags::StopBeforeMatch);
8036+
break;
8037+
}
8038+
80288039
// Inform the actions module about the parameter declarator, so it gets
80298040
// added to the current scope.
80308041
Decl *Param =

clang/lib/Sema/SemaAttr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,13 +1269,12 @@ void Sema::ActOnPragmaFPContract(SourceLocation Loc,
12691269
NewFPFeatures.setAllowFPContractWithinStatement();
12701270
break;
12711271
case LangOptions::FPM_Fast:
1272+
case LangOptions::FPM_FastHonorPragmas:
12721273
NewFPFeatures.setAllowFPContractAcrossStatement();
12731274
break;
12741275
case LangOptions::FPM_Off:
12751276
NewFPFeatures.setDisallowFPContract();
12761277
break;
1277-
case LangOptions::FPM_FastHonorPragmas:
1278-
llvm_unreachable("Should not happen");
12791278
}
12801279
FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
12811280
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,10 +1667,7 @@ class ConstraintRefersToContainingTemplateChecker
16671667
}
16681668

16691669
void CheckNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1670-
assert(D->getDepth() <= TemplateDepth &&
1671-
"Nothing should reference a value below the actual template depth, "
1672-
"depth is likely wrong");
1673-
if (D->getDepth() != TemplateDepth)
1670+
if (D->getDepth() < TemplateDepth)
16741671
Result = true;
16751672

16761673
// Necessary because the type of the NTTP might be what refers to the parent
@@ -1694,10 +1691,7 @@ class ConstraintRefersToContainingTemplateChecker
16941691
using inherited::TransformTemplateTypeParmType;
16951692
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
16961693
TemplateTypeParmTypeLoc TL, bool) {
1697-
assert(TL.getDecl()->getDepth() <= TemplateDepth &&
1698-
"Nothing should reference a value below the actual template depth, "
1699-
"depth is likely wrong");
1700-
if (TL.getDecl()->getDepth() != TemplateDepth)
1694+
if (TL.getDecl()->getDepth() < TemplateDepth)
17011695
Result = true;
17021696
return inherited::TransformTemplateTypeParmType(
17031697
TLB, TL,

clang/lib/StaticAnalyzer/Checkers/Taint.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "clang/StaticAnalyzer/Checkers/Taint.h"
1414
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
15+
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
1516
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
1617
#include <optional>
1718

@@ -256,6 +257,12 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
256257
if (!Sym)
257258
return TaintedSymbols;
258259

260+
// HACK:https://discourse.llvm.org/t/rfc-make-istainted-and-complex-symbols-friends/79570
261+
if (const auto &Opts = State->getAnalysisManager().getAnalyzerOptions();
262+
Sym->computeComplexity() > Opts.MaxTaintedSymbolComplexity) {
263+
return {};
264+
}
265+
259266
// Traverse all the symbols this symbol depends on to see if any are tainted.
260267
for (SymbolRef SubSym : Sym->symbols()) {
261268
if (!isa<SymbolData>(SubSym))

clang/test/Analysis/analyzer-config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
// CHECK-NEXT: max-inlinable-size = 100
9595
// CHECK-NEXT: max-nodes = 225000
9696
// CHECK-NEXT: max-symbol-complexity = 35
97+
// CHECK-NEXT: max-tainted-symbol-complexity = 9
9798
// CHECK-NEXT: max-times-inline-large = 32
9899
// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
99100
// CHECK-NEXT: mode = deep

clang/test/Analysis/taint-generic.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void clang_analyzer_isTainted_char(char);
6363
void clang_analyzer_isTainted_wchar(wchar_t);
6464
void clang_analyzer_isTainted_charp(char*);
6565
void clang_analyzer_isTainted_int(int);
66+
void clang_analyzer_dump_int(int);
6667

6768
int coin();
6869

@@ -459,7 +460,53 @@ unsigned radar11369570_hanging(const unsigned char *arr, int l) {
459460
longcmp(a, t, c);
460461
l -= 12;
461462
}
462-
return 5/a; // expected-warning {{Division by a tainted value, possibly zero}}
463+
return 5/a; // FIXME: Should be a "div by tainted" warning here.
464+
}
465+
466+
// This computation used to take a very long time.
467+
void complex_taint_queries(const int *p) {
468+
int tainted = 0;
469+
scanf("%d", &tainted);
470+
471+
// Make "tmp" tainted.
472+
int tmp = tainted + tainted;
473+
clang_analyzer_isTainted_int(tmp); // expected-warning{{YES}}
474+
475+
// Make "tmp" SymExpr a lot more complicated by applying computation.
476+
// This should balloon the symbol complexity.
477+
tmp += p[0] + p[0];
478+
tmp += p[1] + p[1];
479+
tmp += p[2] + p[2];
480+
clang_analyzer_dump_int(tmp); // expected-warning{{((((conj_}} symbol complexity: 8
481+
clang_analyzer_isTainted_int(tmp); // expected-warning{{YES}}
482+
483+
tmp += p[3] + p[3];
484+
clang_analyzer_dump_int(tmp); // expected-warning{{(((((conj_}} symbol complexity: 10
485+
clang_analyzer_isTainted_int(tmp); // expected-warning{{NO}} 10 is already too complex to be traversed
486+
487+
tmp += p[4] + p[4];
488+
tmp += p[5] + p[5];
489+
tmp += p[6] + p[6];
490+
tmp += p[7] + p[7];
491+
tmp += p[8] + p[8];
492+
tmp += p[9] + p[9];
493+
tmp += p[10] + p[10];
494+
tmp += p[11] + p[11];
495+
tmp += p[12] + p[12];
496+
tmp += p[13] + p[13];
497+
tmp += p[14] + p[14];
498+
tmp += p[15] + p[15];
499+
500+
// The SymExpr still holds the full history of the computation, yet, "isTainted" doesn't traverse the tree as the complexity is over the threshold.
501+
clang_analyzer_dump_int(tmp);
502+
// expected-warning@-1{{(((((((((((((((((conj_}} symbol complexity: 34
503+
clang_analyzer_isTainted_int(tmp); // expected-warning{{NO}} FIXME: Ideally, this should still result in "tainted".
504+
505+
// By making it even one step more complex, then it would hit the "max-symbol-complexity"
506+
// threshold and the engine would cut the SymExpr and replace it by a new conjured symbol.
507+
tmp += p[16];
508+
clang_analyzer_dump_int(tmp); // expected-warning{{conj_}} symbol complexity: 1
509+
clang_analyzer_isTainted_int(tmp); // expected-warning{{NO}}
463510
}
464511

465512
// Check that we do not assert of the following code.

clang/test/ClangScanDeps/pr61006.cppm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
// RUN: mkdir -p %t
77
// RUN: split-file %s %t
88
//
9-
// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \
9+
// RUN: %clang -print-resource-dir > %t/resource-dir.txt && \
1010
// RUN: ln -s %clang++ %t/clang++ && \
11-
// RUN: sed "s|EXPECTED_RESOURCE_DIR|$EXPECTED_RESOURCE_DIR|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \
12-
// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \
13-
// RUN: clang-scan-deps -format=p1689 \
11+
// RUN: sed "s|EXPECTED_RESOURCE_DIR|%{readfile:%t/resource-dir.txt}|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \
12+
// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir.txt} clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \
13+
// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir.txt} clang-scan-deps -format=p1689 \
1414
// RUN: -- %t/clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/a.cpp -o %t/a.o \
15-
// RUN: -resource-dir $EXPECTED_RESOURCE_DIR | FileCheck %t/a.cpp -DPREFIX=%/t
15+
// RUN: -resource-dir %{env:EXPECTED_RESOURCE_DIR} | FileCheck %t/a.cpp -DPREFIX=%/t
1616

1717
//--- P1689.json.in
1818
[
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 -O3 -ffp-contract=fast-honor-pragmas -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
2+
3+
float fp_contract_1(float a, float b, float c) {
4+
// CHECK-LABEL: fp_contract_1fff(
5+
// CHECK: fmul contract float
6+
// CHECK: fadd contract float
7+
return a * b + c;
8+
}
9+
10+
float fp_contract_2(float a, float b, float c) {
11+
// CHECK-LABEL: fp_contract_2fff(
12+
// CHECK: fmul contract float
13+
// CHECK: fsub contract float
14+
return a * b - c;
15+
}
16+
17+
void fp_contract_3(float *a, float b, float c) {
18+
// CHECK-LABEL: fp_contract_3Pfff(
19+
// CHECK: fmul contract float
20+
// CHECK: fadd contract float
21+
a[0] += b * c;
22+
}
23+
24+
void fp_contract_4(float *a, float b, float c) {
25+
// CHECK-LABEL: fp_contract_4Pfff(
26+
// CHECK: fmul contract float
27+
// CHECK: fsub contract float
28+
a[0] -= b * c;
29+
}
30+
31+
float fp_contract_5(float a, float b, float c) {
32+
// CHECK-LABEL: fp_contract_5fff(
33+
// CHECK: fmul contract float
34+
// CHECK: fadd contract float
35+
float t = a * b;
36+
return t + c;
37+
}

0 commit comments

Comments
 (0)