Skip to content

Commit e128f71

Browse files
committed
PR45535: Check for variables with non-trivial destruction when
determining whether a statement expression has side-effects.
1 parent 4b03dd7 commit e128f71

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

clang/lib/AST/Expr.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3270,6 +3270,26 @@ namespace {
32703270

32713271
bool hasSideEffects() const { return HasSideEffects; }
32723272

3273+
void VisitDecl(const Decl *D) {
3274+
if (!D)
3275+
return;
3276+
3277+
// We assume the caller checks subexpressions (eg, the initializer, VLA
3278+
// bounds) for side-effects on our behalf.
3279+
if (auto *VD = dyn_cast<VarDecl>(D)) {
3280+
// Registering a destructor is a side-effect.
3281+
if (IncludePossibleEffects && VD->isThisDeclarationADefinition() &&
3282+
VD->needsDestruction(Context))
3283+
HasSideEffects = true;
3284+
}
3285+
}
3286+
3287+
void VisitDeclStmt(const DeclStmt *DS) {
3288+
for (auto *D : DS->decls())
3289+
VisitDecl(D);
3290+
Inherited::VisitDeclStmt(DS);
3291+
}
3292+
32733293
void VisitExpr(const Expr *E) {
32743294
if (!HasSideEffects &&
32753295
E->HasSideEffects(Context, IncludePossibleEffects))

clang/test/CodeGenCXX/builtin-constant-p.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s
1+
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
22

33
// Don't crash if the argument to __builtin_constant_p isn't scalar.
44
template <typename T>
@@ -22,3 +22,27 @@ class numeric {
2222
bool bcp() {
2323
return is_constant(numeric<int>(1));
2424
}
25+
26+
// PR45535
27+
struct with_dtor {
28+
~with_dtor();
29+
};
30+
// CHECK: define {{.*}}bcp_stmt_expr_1
31+
bool bcp_stmt_expr_1() {
32+
// CHECK-NOT: call {{.*}}with_dtorD
33+
return __builtin_constant_p(({with_dtor wd; 123;}));
34+
}
35+
36+
int do_not_call();
37+
// CHECK: define {{.*}}bcp_stmt_expr_2
38+
bool bcp_stmt_expr_2(int n) {
39+
// CHECK-NOT: call {{.*}}do_not_call
40+
return __builtin_constant_p(({
41+
// This has a side-effect due to the VLA bound, so CodeGen should fold it
42+
// to false.
43+
typedef int arr[do_not_call()];
44+
n;
45+
}));
46+
// CHECK-NOT: }
47+
// CHECK: ret i1 false
48+
}

0 commit comments

Comments
 (0)