Skip to content

Commit e398da2

Browse files
committed
Revert "[Clang] Overflow Pattern Exclusions (#100272)"
This reverts commit 9a666de. Reason: broke buildbots e.g., fork-ubsan.test started failing at https://lab.llvm.org/buildbot/#/builders/66/builds/2819/steps/9/logs/stdio Clang :: CodeGen/compound-assign-overflow.c Clang :: CodeGen/sanitize-atomic-int-overflow.c started failing with https://lab.llvm.org/buildbot/#/builders/52/builds/1570
1 parent 062e69a commit e398da2

File tree

16 files changed

+2
-353
lines changed

16 files changed

+2
-353
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -395,36 +395,6 @@ Moved checkers
395395
Sanitizers
396396
----------
397397

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

clang/docs/UndefinedBehaviorSanitizer.rst

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -293,48 +293,6 @@ 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-
338296
Issue Suppression
339297
=================
340298

clang/include/clang/AST/Expr.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4043,15 +4043,6 @@ 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-
40554046
/// Get FPFeatures from trailing storage
40564047
FPOptionsOverride getStoredFPFeatures() const {
40574048
assert(hasStoredFPFeatures());

clang/include/clang/AST/Stmt.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,6 @@ 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-
658653
SourceLocation OpLoc;
659654
};
660655

clang/include/clang/Basic/LangOptions.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,6 @@ 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")
411409
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
412410

413411
BENIGN_LANGOPT(ArrowDepth, 32, 256,

clang/include/clang/Basic/LangOptions.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -367,21 +367,6 @@ 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-
385370
enum class DefaultVisiblityExportMapping {
386371
None,
387372
/// map only explicit default visibilities to exported
@@ -570,11 +555,6 @@ class LangOptions : public LangOptionsBase {
570555
/// The default stream kind used for HIP kernel launching.
571556
GPUDefaultStreamKind GPUDefaultStream;
572557

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

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

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-
661633
/// Reset all of the options that are not considered when building a
662634
/// module.
663635
void resetNonModularOptions();

clang/include/clang/Driver/Options.td

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,11 +2565,6 @@ 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">>;
25732568
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
25742569
Group<f_clang_Group>,
25752570
HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;

clang/include/clang/Driver/SanitizerArgs.h

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

clang/lib/AST/Expr.cpp

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,53 +4759,6 @@ 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-
48094762
BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
48104763
Opcode opc, QualType ResTy, ExprValueKind VK,
48114764
ExprObjectKind OK, SourceLocation opLoc,
@@ -4815,15 +4768,8 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
48154768
assert(!isCompoundAssignmentOp() &&
48164769
"Use CompoundAssignOperator for compound assignments");
48174770
BinaryOperatorBits.OpLoc = opLoc;
4818-
BinaryOperatorBits.ExcludedOverflowPattern = 0;
48194771
SubExprs[LHS] = lhs;
48204772
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-
}
48274773
BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
48284774
if (hasStoredFPFeatures())
48294775
setStoredFPFeatures(FPFeatures);

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "clang/AST/Attr.h"
2525
#include "clang/AST/DeclObjC.h"
2626
#include "clang/AST/Expr.h"
27-
#include "clang/AST/ParentMapContext.h"
2827
#include "clang/AST/RecordLayout.h"
2928
#include "clang/AST/StmtVisitor.h"
3029
#include "clang/Basic/CodeGenOptions.h"
@@ -196,24 +195,13 @@ static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
196195
if (!Op.mayHaveIntegerOverflow())
197196
return true;
198197

199-
const UnaryOperator *UO = dyn_cast<UnaryOperator>(Op.E);
200-
201-
if (UO && UO->getOpcode() == UO_Minus &&
202-
Ctx.getLangOpts().isOverflowPatternExcluded(
203-
LangOptions::OverflowPatternExclusionKind::NegUnsignedConst) &&
204-
UO->isIntegerConstantExpr(Ctx))
205-
return true;
206-
207198
// If a unary op has a widened operand, the op cannot overflow.
208-
if (UO)
199+
if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
209200
return !UO->canOverflow();
210201

211202
// We usually don't need overflow checks for binops with widened operands.
212203
// Multiplication with promoted unsigned operands is a special case.
213204
const auto *BO = cast<BinaryOperator>(Op.E);
214-
if (BO->hasExcludedOverflowPattern())
215-
return true;
216-
217205
auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
218206
if (!OptionalLHSTy)
219207
return false;
@@ -2778,26 +2766,6 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
27782766
llvm_unreachable("Unknown SignedOverflowBehaviorTy");
27792767
}
27802768

2781-
/// For the purposes of overflow pattern exclusion, does this match the
2782-
/// "while(i--)" pattern?
2783-
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc,
2784-
bool isPre, ASTContext &Ctx) {
2785-
if (isInc || isPre)
2786-
return false;
2787-
2788-
// -fsanitize-overflow-pattern-exclusion=post-decr-while
2789-
if (!Ctx.getLangOpts().isOverflowPatternExcluded(
2790-
LangOptions::OverflowPatternExclusionKind::PostDecrInWhile))
2791-
return false;
2792-
2793-
// all Parents (usually just one) must be a WhileStmt
2794-
for (const auto &Parent : Ctx.getParentMapContext().getParents(*UO))
2795-
if (!Parent.get<WhileStmt>())
2796-
return false;
2797-
2798-
return true;
2799-
}
2800-
28012769
namespace {
28022770
/// Handles check and update for lastprivate conditional variables.
28032771
class OMPLastprivateConditionalUpdateRAII {
@@ -2909,10 +2877,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
29092877
} else if (type->isIntegerType()) {
29102878
QualType promotedType;
29112879
bool canPerformLossyDemotionCheck = false;
2912-
2913-
bool excludeOverflowPattern =
2914-
matchesPostDecrInWhile(E, isInc, isPre, CGF.getContext());
2915-
29162880
if (CGF.getContext().isPromotableIntegerType(type)) {
29172881
promotedType = CGF.getContext().getPromotedIntegerType(type);
29182882
assert(promotedType != type && "Shouldn't promote to the same type.");
@@ -2972,8 +2936,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
29722936
} else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
29732937
value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
29742938
} else if (E->canOverflow() && type->isUnsignedIntegerType() &&
2975-
CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
2976-
!excludeOverflowPattern) {
2939+
CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
29772940
value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
29782941
E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
29792942
} else {

0 commit comments

Comments
 (0)