Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions clang/lib/Analysis/UnsafeBufferUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1650,11 +1650,27 @@ static bool hasAnyBoundsAttributes(const FunctionDecl *FD) {
});
}

// Constant fold a conditional expression 'cond ? A : B' to
// - 'A', if 'cond' has constant true value;
// - 'B', if 'cond' has constant false value.
static const Expr *tryConstantFoldConditionalExpr(const Expr *E,
const ASTContext &Ctx) {
// FIXME: more places can use this function
if (const auto *CE = dyn_cast<ConditionalOperator>(E)) {
bool CondEval;

if (CE->getCond()->EvaluateAsBooleanCondition(CondEval, Ctx))
return CondEval ? CE->getLHS() : CE->getRHS();
}
return E;
}

// A pointer type expression is known to be null-terminated, if
// 1. it is a string literal or `PredefinedExpr` (e.g., `__func__`);
// 2. it has the form: E.c_str(), for any expression E of `std::string` type;
// 3. it has `__null_terminated` type
static bool isNullTermPointer(const Expr *Ptr, ASTContext &Ctx) {
Ptr = tryConstantFoldConditionalExpr(Ptr, Ctx);
if (isa<clang::StringLiteral>(Ptr->IgnoreParenImpCasts()))
return true;
if (isa<PredefinedExpr>(Ptr->IgnoreParenImpCasts()))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %clang_cc1 -fsyntax-only -Wno-all -Wunsafe-buffer-usage -verify %s -std=c++20
// RUN: %clang_cc1 -fsyntax-only -Wno-all -Wunsafe-buffer-usage -verify %s -x c
// expected-no-diagnostics

typedef struct {} FILE;
int fprintf( FILE* stream, const char* format, ... );
FILE * stderr;

#define DEBUG_ASSERT_MESSAGE(name, assertion, label, message, file, line, value) \
fprintf(stderr, "AssertMacros: %s, %s file: %s, line: %d, value: %lld\n", \
assertion, (message!=0) ? message : "", file, line, (long long) (value));


#define Require(assertion, exceptionLabel) \
do \
{ \
if ( __builtin_expect(!(assertion), 0) ) { \
DEBUG_ASSERT_MESSAGE( \
"DEBUG_ASSERT_COMPONENT_NAME_STRING", \
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
goto exceptionLabel; \
} \
} while ( 0 )


void f(int x, int y) {
Require(x == y, L1);
L1:
return;
}