Skip to content

Commit

Permalink
Merged main:99b85cae628c1cc5641944290712cd84ccf1f6c8 into amd-gfx:f09…
Browse files Browse the repository at this point in the history
…ee8740921

Local branch amd-gfx f09ee87 Merged main:c81d6665601d648c1a5349b665ee6019f3786352 into amd-gfx:80a4987ce388
Remote branch main 99b85ca [clang][bytecode][NFC] Add an additional assertion (llvm#105927)
  • Loading branch information
SC llvm team authored and SC llvm team committed Aug 24, 2024
2 parents f09ee87 + 99b85ca commit fee3baa
Show file tree
Hide file tree
Showing 24 changed files with 170 additions and 149 deletions.
20 changes: 13 additions & 7 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -466,28 +466,34 @@ Sanitizers

- Added the ``-fsanitize-undefined-ignore-overflow-pattern`` flag which can be
used to disable specific overflow-dependent code patterns. The supported
patterns are: ``add-overflow-test``, ``negated-unsigned-const``, and
``post-decr-while``. The sanitizer instrumentation can be toggled off for all
available patterns by specifying ``all``. Conversely, you can disable all
exclusions with ``none``.
patterns are: ``add-signed-overflow-test``, ``add-unsigned-overflow-test``,
``negated-unsigned-const``, and ``unsigned-post-decr-while``. The sanitizer
instrumentation can be toggled off for all available patterns by specifying
``all``. Conversely, you may disable all exclusions with ``none`` which is
the default.

.. code-block:: c++

/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-overflow-test``
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-unsigned-overflow-test``
int common_overflow_check_pattern(unsigned base, unsigned offset) {
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented
}
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-signed-overflow-test``
int common_overflow_check_pattern_signed(signed int base, signed int offset) {
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented
}
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const``
void negation_overflow() {
unsigned long foo = -1UL; // No longer causes a negation overflow warning
unsigned long bar = -2UL; // and so on...
}

/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=post-decr-while``
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=unsigned-post-decr-while``
void while_post_decrement() {
unsigned char count = 16;
while (count--) { /* ... */} // No longer causes unsigned-integer-overflow sanitizer to trip
while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip
}
Many existing projects have a large amount of these code patterns present.
Expand Down
37 changes: 30 additions & 7 deletions clang/docs/UndefinedBehaviorSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -314,26 +314,49 @@ Currently, this option supports three overflow-dependent code idioms:
unsigned long foo = -1UL; // No longer causes a negation overflow warning
unsigned long bar = -2UL; // and so on...

``post-decr-while``
``unsigned-post-decr-while``

.. code-block:: c++

/// -fsanitize-undefined-ignore-overflow-pattern=post-decr-while
/// -fsanitize-undefined-ignore-overflow-pattern=unsigned-post-decr-while
unsigned char count = 16;
while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip
``add-overflow-test``
``add-signed-overflow-test,add-unsigned-overflow-test``

.. code-block:: c++

/// -fsanitize-undefined-ignore-overflow-pattern=add-overflow-test
/// -fsanitize-undefined-ignore-overflow-pattern=add-(signed|unsigned)-overflow-test
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings,
// won't be instrumented (same for signed types)
// won't be instrumented (signed or unsigned types)
.. list-table:: Overflow Pattern Types
:widths: 30 50
:header-rows: 1

* - Pattern
- Sanitizer
* - negated-unsigned-const
- unsigned-integer-overflow
* - unsigned-post-decr-while
- unsigned-integer-overflow
* - add-unsigned-overflow-test
- unsigned-integer-overflow
* - add-signed-overflow-test
- signed-integer-overflow



Note: ``add-signed-overflow-test`` suppresses only the check for Undefined
Behavior. Eager Undefined Behavior optimizations are still possible. One may
remedy this with ``-fwrapv`` or ``-fno-strict-overflow``.

You can enable all exclusions with
``-fsanitize-undefined-ignore-overflow-pattern=all`` or disable all exclusions
with ``-fsanitize-undefined-ignore-overflow-pattern=none``. Specifying ``none``
has precedence over other values.
with ``-fsanitize-undefined-ignore-overflow-pattern=none``. If
``-fsanitize-undefined-ignore-overflow-pattern`` is not specified ``none`` is
implied. Specifying ``none`` alongside other values also implies ``none`` as
``none`` has precedence over other values -- including ``all``.

Issue Suppression
=================
Expand Down
8 changes: 5 additions & 3 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,13 @@ class LangOptionsBase {
/// Exclude all overflow patterns (below)
All = 1 << 1,
/// if (a + b < a)
AddOverflowTest = 1 << 2,
AddSignedOverflowTest = 1 << 2,
/// if (a + b < a)
AddUnsignedOverflowTest = 1 << 3,
/// -1UL
NegUnsignedConst = 1 << 3,
NegUnsignedConst = 1 << 4,
/// while (count--)
PostDecrInWhile = 1 << 4,
PostDecrInWhile = 1 << 5,
};

enum class DefaultVisiblityExportMapping {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2570,7 +2570,7 @@ defm sanitize_stats : BoolOption<"f", "sanitize-stats",
def fsanitize_undefined_ignore_overflow_pattern_EQ : CommaJoined<["-"], "fsanitize-undefined-ignore-overflow-pattern=">,
HelpText<"Specify the overflow patterns to exclude from artihmetic sanitizer instrumentation">,
Visibility<[ClangOption, CC1Option]>,
Values<"none,all,add-overflow-test,negated-unsigned-const,post-decr-while">,
Values<"none,all,add-unsigned-overflow-test,add-signed-overflow-test,negated-unsigned-const,unsigned-post-decr-while">,
MarshallingInfoStringVector<LangOpts<"OverflowPatternExclusionValues">>;
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
Group<f_clang_Group>,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ByteCode/IntegralAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ template <bool Signed> class IntegralAP final {

unsigned countLeadingZeros() const { return V.countl_zero(); }

void print(llvm::raw_ostream &OS) const { OS << V; }
void print(llvm::raw_ostream &OS) const { V.print(OS, Signed);}
std::string toDiagnosticString(const ASTContext &Ctx) const {
std::string NameStr;
llvm::raw_string_ostream OS(NameStr);
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2608,9 +2608,11 @@ inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
// the function we're about to call is a lambda call operator,
// skip the CheckInvoke, since the ThisPtr is a null pointer
// anyway.
if (!(S.Current->getFunction() &&
S.Current->getFunction()->isLambdaStaticInvoker() &&
Func->isLambdaCallOperator())) {
if (S.Current->getFunction() &&
S.Current->getFunction()->isLambdaStaticInvoker() &&
Func->isLambdaCallOperator()) {
assert(ThisPtr.isZero());
} else {
if (!CheckInvoke(S, OpPC, ThisPtr))
return false;
}
Expand Down
27 changes: 21 additions & 6 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4806,6 +4806,26 @@ getOverflowPatternBinOp(const BinaryOperator *E) {
return {};
}

/// Compute and set the OverflowPatternExclusion bit based on whether the
/// BinaryOperator expression matches an overflow pattern being ignored by
/// -fsanitize-undefined-ignore-overflow-pattern=add-signed-overflow-test or
/// -fsanitize-undefined-ignore-overflow-pattern=add-unsigned-overflow-test
static void computeOverflowPatternExclusion(const ASTContext &Ctx,
const BinaryOperator *E) {
std::optional<BinaryOperator *> Result = getOverflowPatternBinOp(E);
if (!Result.has_value())
return;
QualType AdditionResultType = Result.value()->getType();

if ((AdditionResultType->isSignedIntegerType() &&
Ctx.getLangOpts().isOverflowPatternExcluded(
LangOptions::OverflowPatternExclusionKind::AddSignedOverflowTest)) ||
(AdditionResultType->isUnsignedIntegerType() &&
Ctx.getLangOpts().isOverflowPatternExcluded(
LangOptions::OverflowPatternExclusionKind::AddUnsignedOverflowTest)))
Result.value()->setExcludedOverflowPattern(true);
}

BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
Opcode opc, QualType ResTy, ExprValueKind VK,
ExprObjectKind OK, SourceLocation opLoc,
Expand All @@ -4818,12 +4838,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
BinaryOperatorBits.ExcludedOverflowPattern = false;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
if (Ctx.getLangOpts().isOverflowPatternExcluded(
LangOptions::OverflowPatternExclusionKind::AddOverflowTest)) {
std::optional<BinaryOperator *> Result = getOverflowPatternBinOp(this);
if (Result.has_value())
Result.value()->BinaryOperatorBits.ExcludedOverflowPattern = true;
}
computeOverflowPatternExclusion(Ctx, this);
BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
if (hasStoredFPFeatures())
setStoredFPFeatures(FPFeatures);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2785,7 +2785,7 @@ static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc,
if (isInc || isPre)
return false;

// -fsanitize-undefined-ignore-overflow-pattern=post-decr-while
// -fsanitize-undefined-ignore-overflow-pattern=unsigned-post-decr-while
if (!Ctx.getLangOpts().isOverflowPatternExcluded(
LangOptions::OverflowPatternExclusionKind::PostDecrInWhile))
return false;
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/Driver/SanitizerArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1457,9 +1457,12 @@ static int parseOverflowPatternExclusionValues(const Driver &D,
llvm::StringSwitch<int>(Value)
.Case("none", LangOptionsBase::None)
.Case("all", LangOptionsBase::All)
.Case("add-overflow-test", LangOptionsBase::AddOverflowTest)
.Case("add-unsigned-overflow-test",
LangOptionsBase::AddUnsignedOverflowTest)
.Case("add-signed-overflow-test",
LangOptionsBase::AddSignedOverflowTest)
.Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
.Case("post-decr-while", LangOptionsBase::PostDecrInWhile)
.Case("unsigned-post-decr-while", LangOptionsBase::PostDecrInWhile)
.Default(0);
if (E == 0)
D.Diag(clang::diag::err_drv_unsupported_option_argument)
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4274,9 +4274,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
llvm::StringSwitch<unsigned>(A->getValue(i))
.Case("none", LangOptionsBase::None)
.Case("all", LangOptionsBase::All)
.Case("add-overflow-test", LangOptionsBase::AddOverflowTest)
.Case("add-unsigned-overflow-test",
LangOptionsBase::AddUnsignedOverflowTest)
.Case("add-signed-overflow-test",
LangOptionsBase::AddSignedOverflowTest)
.Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
.Case("post-decr-while", LangOptionsBase::PostDecrInWhile)
.Case("unsigned-post-decr-while",
LangOptionsBase::PostDecrInWhile)
.Default(0);
}
}
Expand Down
Loading

0 comments on commit fee3baa

Please sign in to comment.