Skip to content

Commit 4058751

Browse files
committed
Merge commit '3f60d220514c' from llvm.org/main into next
Conflicts: clang/lib/Analysis/UnsafeBufferUsage.cpp
2 parents bd78e2a + 3f60d22 commit 4058751

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,11 +1656,27 @@ static bool hasAnyBoundsAttributes(const FunctionDecl *FD) {
16561656
});
16571657
}
16581658

1659+
// Constant fold a conditional expression 'cond ? A : B' to
1660+
// - 'A', if 'cond' has constant true value;
1661+
// - 'B', if 'cond' has constant false value.
1662+
static const Expr *tryConstantFoldConditionalExpr(const Expr *E,
1663+
const ASTContext &Ctx) {
1664+
// FIXME: more places can use this function
1665+
if (const auto *CE = dyn_cast<ConditionalOperator>(E)) {
1666+
bool CondEval;
1667+
1668+
if (CE->getCond()->EvaluateAsBooleanCondition(CondEval, Ctx))
1669+
return CondEval ? CE->getLHS() : CE->getRHS();
1670+
}
1671+
return E;
1672+
}
1673+
16591674
// A pointer type expression is known to be null-terminated, if
16601675
// 1. it is a string literal or `PredefinedExpr` (e.g., `__func__`);
16611676
// 2. it has the form: E.c_str(), for any expression E of `std::string` type;
16621677
// 3. it has `__null_terminated` type
16631678
static bool isNullTermPointer(const Expr *Ptr, ASTContext &Ctx) {
1679+
Ptr = tryConstantFoldConditionalExpr(Ptr, Ctx);
16641680
if (isa<clang::StringLiteral>(Ptr->IgnoreParenImpCasts()))
16651681
return true;
16661682
if (isa<PredefinedExpr>(Ptr->IgnoreParenImpCasts()))
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -fsyntax-only -Wno-all -Wunsafe-buffer-usage -verify %s -std=c++20
2+
// RUN: %clang_cc1 -fsyntax-only -Wno-all -Wunsafe-buffer-usage -verify %s -x c
3+
// expected-no-diagnostics
4+
5+
typedef struct {} FILE;
6+
int fprintf( FILE* stream, const char* format, ... );
7+
FILE * stderr;
8+
9+
#define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
10+
fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d, value: %lld\n", \
11+
assertion, (message!=0) ? message : "", file, line, (long long) (value));
12+
13+
14+
#define Require(assertion, exceptionLabel) \
15+
do \
16+
{ \
17+
if ( __builtin_expect(!(assertion), 0) ) { \
18+
DEBUG_ASSERT_MESSAGE( \
19+
"DEBUG_ASSERT_COMPONENT_NAME_STRING", \
20+
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
21+
goto exceptionLabel; \
22+
} \
23+
} while ( 0 )
24+
25+
26+
void f(int x, int y) {
27+
Require(x == y, L1);
28+
L1:
29+
return;
30+
}
31+

0 commit comments

Comments
 (0)