forked from OSchip/llvm-project
PR45535: Check for variables with non-trivial destruction when
determining whether a statement expression has side-effects.
This commit is contained in:
parent
4b03dd7b84
commit
e128f710ea
clang
|
@ -3270,6 +3270,26 @@ namespace {
|
||||||
|
|
||||||
bool hasSideEffects() const { return HasSideEffects; }
|
bool hasSideEffects() const { return HasSideEffects; }
|
||||||
|
|
||||||
|
void VisitDecl(const Decl *D) {
|
||||||
|
if (!D)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We assume the caller checks subexpressions (eg, the initializer, VLA
|
||||||
|
// bounds) for side-effects on our behalf.
|
||||||
|
if (auto *VD = dyn_cast<VarDecl>(D)) {
|
||||||
|
// Registering a destructor is a side-effect.
|
||||||
|
if (IncludePossibleEffects && VD->isThisDeclarationADefinition() &&
|
||||||
|
VD->needsDestruction(Context))
|
||||||
|
HasSideEffects = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisitDeclStmt(const DeclStmt *DS) {
|
||||||
|
for (auto *D : DS->decls())
|
||||||
|
VisitDecl(D);
|
||||||
|
Inherited::VisitDeclStmt(DS);
|
||||||
|
}
|
||||||
|
|
||||||
void VisitExpr(const Expr *E) {
|
void VisitExpr(const Expr *E) {
|
||||||
if (!HasSideEffects &&
|
if (!HasSideEffects &&
|
||||||
E->HasSideEffects(Context, IncludePossibleEffects))
|
E->HasSideEffects(Context, IncludePossibleEffects))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s
|
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
|
||||||
|
|
||||||
// Don't crash if the argument to __builtin_constant_p isn't scalar.
|
// Don't crash if the argument to __builtin_constant_p isn't scalar.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -22,3 +22,27 @@ class numeric {
|
||||||
bool bcp() {
|
bool bcp() {
|
||||||
return is_constant(numeric<int>(1));
|
return is_constant(numeric<int>(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR45535
|
||||||
|
struct with_dtor {
|
||||||
|
~with_dtor();
|
||||||
|
};
|
||||||
|
// CHECK: define {{.*}}bcp_stmt_expr_1
|
||||||
|
bool bcp_stmt_expr_1() {
|
||||||
|
// CHECK-NOT: call {{.*}}with_dtorD
|
||||||
|
return __builtin_constant_p(({with_dtor wd; 123;}));
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_not_call();
|
||||||
|
// CHECK: define {{.*}}bcp_stmt_expr_2
|
||||||
|
bool bcp_stmt_expr_2(int n) {
|
||||||
|
// CHECK-NOT: call {{.*}}do_not_call
|
||||||
|
return __builtin_constant_p(({
|
||||||
|
// This has a side-effect due to the VLA bound, so CodeGen should fold it
|
||||||
|
// to false.
|
||||||
|
typedef int arr[do_not_call()];
|
||||||
|
n;
|
||||||
|
}));
|
||||||
|
// CHECK-NOT: }
|
||||||
|
// CHECK: ret i1 false
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue