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
|
@ -3270,6 +3270,26 @@ namespace {
|
|||
|
||||
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) {
|
||||
if (!HasSideEffects &&
|
||||
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.
|
||||
template <typename T>
|
||||
|
@ -22,3 +22,27 @@ class numeric {
|
|||
bool bcp() {
|
||||
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