aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-05-16 09:32:51 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-05-16 09:32:51 +0000
commit761c94e3bffef0fcb8b4bbf202fd5ee73db134f3 (patch)
tree5d9702e6f4b49d4dcb3e39843776380fe643edcc
parent4bb3bf98704c98d2953381b484a9127f0909678f (diff)
When constant folding reference variables with an initializer to the
initializer, don't fold paramters. Their initializers are just default arguments which can be overridden. This fixes some spectacular regressions due to more things making it into the constant folding. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103904 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ExprConstant.cpp4
-rw-r--r--test/CodeGenCXX/references.cpp13
2 files changed, 17 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index f903035d22..dc614018ec 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -355,6 +355,10 @@ bool LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
} else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
if (!VD->getType()->isReferenceType())
return Success(E);
+ // Reference parameters can refer to anything even if they have an
+ // "initializer" in the form of a default argument.
+ if (isa<ParmVarDecl>(VD))
+ return false;
// FIXME: Check whether VD might be overridden!
if (const Expr *Init = VD->getAnyInitializer())
return Visit(const_cast<Expr *>(Init));
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 5a5947dd81..3ae1e474f8 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -155,3 +155,16 @@ void f0(s1 a) { s1 b = a; }
// CHECK: load
// CHECK: ret
const int &f2() { return 0; }
+
+// Don't constant fold const reference parameters with default arguments to
+// their default arguments.
+namespace N1 {
+ const int foo = 1;
+ // CHECK: @_ZN2N14test
+ int test(const int& arg = foo) {
+ // Ensure this array is on the stack where we can set values instead of
+ // being a global constant.
+ // CHECK: %args_array = alloca
+ const int* const args_array[] = { &arg };
+ }
+}