Author: rsmith Date: Tue Oct 8 14:26:03 2019 New Revision: 374119 URL: http://llvm.org/viewvc/llvm-project?rev=374119&view=rev Log: Fix crash or wrong code bug if a lifetime-extended temporary contains a "non-constant" value.
If the constant evaluator evaluates part of a variable initializer, including the initializer for some lifetime-extended temporary, but fails to fully evaluate the initializer, it can leave behind wrong values for temporaries encountered in that initialization. Don't try to emit those from CodeGen! Instead, look at the values that constant evaluation produced if (and only if) it actually succeeds and we're emitting the lifetime-extending declaration's initializer as a constant. Added: cfe/trunk/test/CodeGenCXX/no-const-init-cxx2a.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CodeGenModule.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=374119&r1=374118&r2=374119&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Oct 8 14:26:03 2019 @@ -13569,8 +13569,10 @@ bool Expr::EvaluateAsConstantExpr(EvalRe if (!Info.discardCleanups()) llvm_unreachable("Unhandled cleanup; missing full expression marker?"); - return CheckConstantExpression(Info, getExprLoc(), getType(), Result.Val, - Usage) && + QualType T = getType(); + if (!isRValue()) + T = Ctx.getLValueReferenceType(T); + return CheckConstantExpression(Info, getExprLoc(), T, Result.Val, Usage) && CheckMemoryLeaks(Info); } Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=374119&r1=374118&r2=374119&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Oct 8 14:26:03 2019 @@ -4978,14 +4978,13 @@ ConstantAddress CodeGenModule::GetAddrOf VD, E->getManglingNumber(), Out); APValue *Value = nullptr; - if (E->getStorageDuration() == SD_Static) { - // We might have a cached constant initializer for this temporary. Note - // that this might have a different value from the value computed by - // evaluating the initializer if the surrounding constant expression - // modifies the temporary. + if (E->getStorageDuration() == SD_Static && VD && VD->evaluateValue()) { + // If the initializer of the extending declaration is a constant + // initializer, we should have a cached constant initializer for this + // temporary. Note that this might have a different value from the value + // computed by evaluating the initializer if the surrounding constant + // expression modifies the temporary. Value = getContext().getMaterializedTemporaryValue(E, false); - if (Value && Value->isAbsent()) - Value = nullptr; } // Try evaluating it now, it might have a constant initializer. Added: cfe/trunk/test/CodeGenCXX/no-const-init-cxx2a.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/no-const-init-cxx2a.cpp?rev=374119&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/no-const-init-cxx2a.cpp (added) +++ cfe/trunk/test/CodeGenCXX/no-const-init-cxx2a.cpp Tue Oct 8 14:26:03 2019 @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -std=c++2a | FileCheck %s + +// CHECK-DAG: @p = {{.*}} null +// CHECK-DAG: @_ZGR1p_ = {{.*}} null +int *const &p = new int; + +struct d { + constexpr d(int &&f) : e(f) {} + int &e; +}; + +// CHECK-DAG: @g = {{.*}} null +// CHECK-DAG: @_ZGR1g_ = {{.*}} zeroinitializer +d &&g{{0}}; + +// CHECK: define {{.*}} @__cxx_global_var_init +// CHECK: define {{.*}} @__cxx_global_var_init +// CHECK-NOT: define {{.*}} @__cxx_global_var_init _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits