Skip to content

Commit 4afe17e

Browse files
committed
[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.5-bogner [skip ci]
2 parents 9259b07 + 8107810 commit 4afe17e

File tree

177 files changed

+4530
-1517
lines changed

Some content is hidden

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

177 files changed

+4530
-1517
lines changed

clang-tools-extra/include-cleaner/lib/WalkAST.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,13 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
271271
// specialized template. Implicit ones are filtered out by RAV.
272272
bool
273273
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *CTSD) {
274-
// if (CTSD->isExplicitSpecialization())
275274
if (clang::isTemplateExplicitInstantiationOrSpecialization(
276275
CTSD->getTemplateSpecializationKind()))
277276
report(CTSD->getLocation(),
278277
CTSD->getSpecializedTemplate()->getTemplatedDecl());
279278
return true;
280279
}
281280
bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *VTSD) {
282-
// if (VTSD->isExplicitSpecialization())
283281
if (clang::isTemplateExplicitInstantiationOrSpecialization(
284282
VTSD->getTemplateSpecializationKind()))
285283
report(VTSD->getLocation(),

clang/docs/ReleaseNotes.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,20 @@ C++ Specific Potentially Breaking Changes
6565
`-Wno-enum-constexpr-conversion`, to allow for a transition period for users.
6666
Now, in Clang 20, **it is no longer possible to suppress the diagnostic**.
6767

68+
- Extraneous template headers are now ill-formed by default.
69+
This error can be disable with ``-Wno-error=extraneous-template-head``.
70+
71+
.. code-block:: c++
72+
73+
template <> // error: extraneous template head
74+
template <typename T>
75+
void f();
76+
6877
ABI Changes in This Version
6978
---------------------------
7079

80+
- Fixed Microsoft name mangling of placeholder, auto and decltype(auto), return types for MSVC 1920+. This change resolves incompatibilities with code compiled by MSVC 1920+ but will introduce incompatibilities with code compiled by earlier versions of Clang unless such code is built with the compiler option -fms-compatibility-version=19.14 to imitate the MSVC 1914 mangling behavior.
81+
7182
AST Dumping Potentially Breaking Changes
7283
----------------------------------------
7384

@@ -383,6 +394,36 @@ Moved checkers
383394
Sanitizers
384395
----------
385396

397+
- Added the ``-fsanitize-overflow-pattern-exclusion=`` flag which can be used
398+
to disable specific overflow-dependent code patterns. The supported patterns
399+
are: ``add-overflow-test``, ``negated-unsigned-const``, and
400+
``post-decr-while``. The sanitizer instrumentation can be toggled off for all
401+
available patterns by specifying ``all``. Conversely, you can disable all
402+
exclusions with ``none``.
403+
404+
.. code-block:: c++
405+
406+
/// specified with ``-fsanitize-overflow-pattern-exclusion=add-overflow-test``
407+
int common_overflow_check_pattern(unsigned base, unsigned offset) {
408+
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented
409+
}
410+
411+
/// specified with ``-fsanitize-overflow-pattern-exclusion=negated-unsigned-const``
412+
void negation_overflow() {
413+
unsigned long foo = -1UL; // No longer causes a negation overflow warning
414+
unsigned long bar = -2UL; // and so on...
415+
}
416+
417+
/// specified with ``-fsanitize-overflow-pattern-exclusion=post-decr-while``
418+
void while_post_decrement() {
419+
unsigned char count = 16;
420+
while (count--) { /* ... */} // No longer causes unsigned-integer-overflow sanitizer to trip
421+
}
422+
423+
Many existing projects have a large amount of these code patterns present.
424+
This new flag should allow those projects to enable integer sanitizers with
425+
less noise.
426+
386427
Python Binding Changes
387428
----------------------
388429
- Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``.

clang/docs/UndefinedBehaviorSanitizer.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,48 @@ To silence reports from unsigned integer overflow, you can set
293293
``-fsanitize-recover=unsigned-integer-overflow``, is particularly useful for
294294
providing fuzzing signal without blowing up logs.
295295

296+
Disabling instrumentation for common overflow patterns
297+
------------------------------------------------------
298+
299+
There are certain overflow-dependent or overflow-prone code patterns which
300+
produce a lot of noise for integer overflow/truncation sanitizers. Negated
301+
unsigned constants, post-decrements in a while loop condition and simple
302+
overflow checks are accepted and pervasive code patterns. However, the signal
303+
received from sanitizers instrumenting these code patterns may be too noisy for
304+
some projects. To disable instrumentation for these common patterns one should
305+
use ``-fsanitize-overflow-pattern-exclusion=``.
306+
307+
Currently, this option supports three overflow-dependent code idioms:
308+
309+
``negated-unsigned-const``
310+
311+
.. code-block:: c++
312+
313+
/// -fsanitize-overflow-pattern-exclusion=negated-unsigned-const
314+
unsigned long foo = -1UL; // No longer causes a negation overflow warning
315+
unsigned long bar = -2UL; // and so on...
316+
317+
``post-decr-while``
318+
319+
.. code-block:: c++
320+
321+
/// -fsanitize-overflow-pattern-exclusion=post-decr-while
322+
unsigned char count = 16;
323+
while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip
324+
325+
``add-overflow-test``
326+
327+
.. code-block:: c++
328+
329+
/// -fsanitize-overflow-pattern-exclusion=add-overflow-test
330+
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings,
331+
// won't be instrumented (same for signed types)
332+
333+
You can enable all exclusions with
334+
``-fsanitize-overflow-pattern-exclusion=all`` or disable all exclusions with
335+
``-fsanitize-overflow-pattern-exclusion=none``. Specifying ``none`` has
336+
precedence over other values.
337+
296338
Issue Suppression
297339
=================
298340

clang/include/clang/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3206,6 +3206,10 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
32063206
/// Set the C++11 in-class initializer for this member.
32073207
void setInClassInitializer(Expr *NewInit);
32083208

3209+
/// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
3210+
/// \p nullptr if either the attribute or the field doesn't exist.
3211+
const FieldDecl *findCountedByField() const;
3212+
32093213
private:
32103214
void setLazyInClassInitializer(LazyDeclStmtPtr NewInit);
32113215

clang/include/clang/AST/Expr.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4043,6 +4043,15 @@ class BinaryOperator : public Expr {
40434043
void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; }
40444044
bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
40454045

4046+
/// Set and get the bit that informs arithmetic overflow sanitizers whether
4047+
/// or not they should exclude certain BinaryOperators from instrumentation
4048+
void setExcludedOverflowPattern(bool B) {
4049+
BinaryOperatorBits.ExcludedOverflowPattern = B;
4050+
}
4051+
bool hasExcludedOverflowPattern() const {
4052+
return BinaryOperatorBits.ExcludedOverflowPattern;
4053+
}
4054+
40464055
/// Get FPFeatures from trailing storage
40474056
FPOptionsOverride getStoredFPFeatures() const {
40484057
assert(hasStoredFPFeatures());

clang/include/clang/AST/Stmt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,11 @@ class alignas(void *) Stmt {
650650
LLVM_PREFERRED_TYPE(bool)
651651
unsigned HasFPFeatures : 1;
652652

653+
/// Whether or not this BinaryOperator should be excluded from integer
654+
/// overflow sanitization.
655+
LLVM_PREFERRED_TYPE(bool)
656+
unsigned ExcludedOverflowPattern : 1;
657+
653658
SourceLocation OpLoc;
654659
};
655660

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5428,7 +5428,8 @@ def err_template_spec_extra_headers : Error<
54285428
"extraneous template parameter list in template specialization or "
54295429
"out-of-line template definition">;
54305430
def ext_template_spec_extra_headers : ExtWarn<
5431-
"extraneous template parameter list in template specialization">;
5431+
"extraneous template parameter list in template specialization">,
5432+
InGroup<DiagGroup<"extraneous-template-head">>, DefaultError;
54325433
def note_explicit_template_spec_does_not_need_header : Note<
54335434
"'template<>' header not required for explicitly-specialized class %0 "
54345435
"declared here">;

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
406406
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
407407
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
408408
"signed integer overflow handling")
409+
LANGOPT(IgnoreNegationOverflow, 1, 0, "ignore overflow caused by negation")
410+
LANGOPT(SanitizeOverflowIdioms, 1, 1, "enable instrumentation for common overflow idioms")
409411
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
410412

411413
BENIGN_LANGOPT(ArrowDepth, 32, 256,

clang/include/clang/Basic/LangOptions.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,21 @@ class LangOptionsBase {
367367
PerThread,
368368
};
369369

370+
/// Exclude certain code patterns from being instrumented by arithmetic
371+
/// overflow sanitizers
372+
enum OverflowPatternExclusionKind {
373+
/// Don't exclude any overflow patterns from sanitizers
374+
None = 1 << 0,
375+
/// Exclude all overflow patterns (below)
376+
All = 1 << 1,
377+
/// if (a + b < a)
378+
AddOverflowTest = 1 << 2,
379+
/// -1UL
380+
NegUnsignedConst = 1 << 3,
381+
/// while (count--)
382+
PostDecrInWhile = 1 << 4,
383+
};
384+
370385
enum class DefaultVisiblityExportMapping {
371386
None,
372387
/// map only explicit default visibilities to exported
@@ -555,6 +570,11 @@ class LangOptions : public LangOptionsBase {
555570
/// The default stream kind used for HIP kernel launching.
556571
GPUDefaultStreamKind GPUDefaultStream;
557572

573+
/// Which overflow patterns should be excluded from sanitizer instrumentation
574+
unsigned OverflowPatternExclusionMask = 0;
575+
576+
std::vector<std::string> OverflowPatternExclusionValues;
577+
558578
/// The seed used by the randomize structure layout feature.
559579
std::string RandstructSeed;
560580

@@ -630,6 +650,14 @@ class LangOptions : public LangOptionsBase {
630650
return MSCompatibilityVersion >= MajorVersion * 100000U;
631651
}
632652

653+
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const {
654+
if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::None)
655+
return false;
656+
if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::All)
657+
return true;
658+
return OverflowPatternExclusionMask & Kind;
659+
}
660+
633661
/// Reset all of the options that are not considered when building a
634662
/// module.
635663
void resetNonModularOptions();

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,11 @@ defm sanitize_stats : BoolOption<"f", "sanitize-stats",
25652565
"Disable">,
25662566
BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>,
25672567
Group<f_clang_Group>;
2568+
def fsanitize_overflow_pattern_exclusion_EQ : CommaJoined<["-"], "fsanitize-overflow-pattern-exclusion=">,
2569+
HelpText<"Specify the overflow patterns to exclude from artihmetic sanitizer instrumentation">,
2570+
Visibility<[ClangOption, CC1Option]>,
2571+
Values<"none,all,add-overflow-test,negated-unsigned-const,post-decr-while">,
2572+
MarshallingInfoStringVector<LangOpts<"OverflowPatternExclusionValues">>;
25682573
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
25692574
Group<f_clang_Group>,
25702575
HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class SanitizerArgs {
3333
std::vector<std::string> BinaryMetadataIgnorelistFiles;
3434
int CoverageFeatures = 0;
3535
int BinaryMetadataFeatures = 0;
36+
int OverflowPatternExclusions = 0;
3637
int MsanTrackOrigins = 0;
3738
bool MsanUseAfterDtor = true;
3839
bool MsanParamRetval = true;

clang/lib/AST/Decl.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4678,6 +4678,19 @@ void FieldDecl::printName(raw_ostream &OS, const PrintingPolicy &Policy) const {
46784678
DeclaratorDecl::printName(OS, Policy);
46794679
}
46804680

4681+
const FieldDecl *FieldDecl::findCountedByField() const {
4682+
const auto *CAT = getType()->getAs<CountAttributedType>();
4683+
if (!CAT)
4684+
return nullptr;
4685+
4686+
const auto *CountDRE = cast<DeclRefExpr>(CAT->getCountExpr());
4687+
const auto *CountDecl = CountDRE->getDecl();
4688+
if (const auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl))
4689+
CountDecl = IFD->getAnonField();
4690+
4691+
return dyn_cast<FieldDecl>(CountDecl);
4692+
}
4693+
46814694
//===----------------------------------------------------------------------===//
46824695
// TagDecl Implementation
46834696
//===----------------------------------------------------------------------===//

clang/lib/AST/Expr.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,6 +4759,53 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
47594759
return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
47604760
}
47614761

4762+
/// Certain overflow-dependent code patterns can have their integer overflow
4763+
/// sanitization disabled. Check for the common pattern `if (a + b < a)` and
4764+
/// return the resulting BinaryOperator responsible for the addition so we can
4765+
/// elide overflow checks during codegen.
4766+
static std::optional<BinaryOperator *>
4767+
getOverflowPatternBinOp(const BinaryOperator *E) {
4768+
Expr *Addition, *ComparedTo;
4769+
if (E->getOpcode() == BO_LT) {
4770+
Addition = E->getLHS();
4771+
ComparedTo = E->getRHS();
4772+
} else if (E->getOpcode() == BO_GT) {
4773+
Addition = E->getRHS();
4774+
ComparedTo = E->getLHS();
4775+
} else {
4776+
return {};
4777+
}
4778+
4779+
const Expr *AddLHS = nullptr, *AddRHS = nullptr;
4780+
BinaryOperator *BO = dyn_cast<BinaryOperator>(Addition);
4781+
4782+
if (BO && BO->getOpcode() == clang::BO_Add) {
4783+
// now store addends for lookup on other side of '>'
4784+
AddLHS = BO->getLHS();
4785+
AddRHS = BO->getRHS();
4786+
}
4787+
4788+
if (!AddLHS || !AddRHS)
4789+
return {};
4790+
4791+
const Decl *LHSDecl, *RHSDecl, *OtherDecl;
4792+
4793+
LHSDecl = AddLHS->IgnoreParenImpCasts()->getReferencedDeclOfCallee();
4794+
RHSDecl = AddRHS->IgnoreParenImpCasts()->getReferencedDeclOfCallee();
4795+
OtherDecl = ComparedTo->IgnoreParenImpCasts()->getReferencedDeclOfCallee();
4796+
4797+
if (!OtherDecl)
4798+
return {};
4799+
4800+
if (!LHSDecl && !RHSDecl)
4801+
return {};
4802+
4803+
if ((LHSDecl && LHSDecl == OtherDecl && LHSDecl != RHSDecl) ||
4804+
(RHSDecl && RHSDecl == OtherDecl && RHSDecl != LHSDecl))
4805+
return BO;
4806+
return {};
4807+
}
4808+
47624809
BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
47634810
Opcode opc, QualType ResTy, ExprValueKind VK,
47644811
ExprObjectKind OK, SourceLocation opLoc,
@@ -4768,8 +4815,15 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
47684815
assert(!isCompoundAssignmentOp() &&
47694816
"Use CompoundAssignOperator for compound assignments");
47704817
BinaryOperatorBits.OpLoc = opLoc;
4818+
BinaryOperatorBits.ExcludedOverflowPattern = 0;
47714819
SubExprs[LHS] = lhs;
47724820
SubExprs[RHS] = rhs;
4821+
if (Ctx.getLangOpts().isOverflowPatternExcluded(
4822+
LangOptions::OverflowPatternExclusionKind::AddOverflowTest)) {
4823+
std::optional<BinaryOperator *> Result = getOverflowPatternBinOp(this);
4824+
if (Result.has_value())
4825+
Result.value()->BinaryOperatorBits.ExcludedOverflowPattern = 1;
4826+
}
47734827
BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
47744828
if (hasStoredFPFeatures())
47754829
setStoredFPFeatures(FPFeatures);

0 commit comments

Comments
 (0)