]> granicus.if.org Git - clang/commitdiff
Sema: prevent assertion on stack return checking
authorSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 15 Feb 2016 01:51:24 +0000 (01:51 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 15 Feb 2016 01:51:24 +0000 (01:51 +0000)
In the case that the array indexing itself is within a type dependent context,
bail out of the evaluation.  We would previously try to symbolically evaluate
the expression which would then try to evaluate a non-address expression as an
address, triggering an assertion in Asserts builds.

We only need to consider the array subscript expression itself as in the case
that the base itself being type dependent is handled appropriately in EvalAddr.

Resolves PR26599.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260867 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/SemaCXX/return-stack-addr-2.cpp [new file with mode: 0644]

index 227079f342dd3d239ccd9dcc30eb71926a30d259..db29e720054db8600f1a32c65da2669897c16415 100644 (file)
@@ -6144,8 +6144,10 @@ static const Expr *EvalVal(const Expr *E,
       // Array subscripts are potential references to data on the stack.  We
       // retrieve the DeclRefExpr* for the array variable if it indeed
       // has local storage.
-      return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase(), refVars,
-                      ParentDecl);
+      const auto *ASE = cast<ArraySubscriptExpr>(E);
+      if (ASE->isTypeDependent())
+        return nullptr;
+      return EvalAddr(ASE->getBase(), refVars, ParentDecl);
     }
 
     case Stmt::OMPArraySectionExprClass: {
diff --git a/test/SemaCXX/return-stack-addr-2.cpp b/test/SemaCXX/return-stack-addr-2.cpp
new file mode 100644 (file)
index 0000000..ad27567
--- /dev/null
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+namespace PR26599 {
+template <typename>
+struct S;
+
+struct I {};
+
+template <typename T>
+void *&non_pointer() {
+  void *&r = S<T>()[I{}];
+  return r;
+}
+
+template <typename T>
+void *&pointer() {
+  void *&r = S<T>()[nullptr];
+  return r;
+}
+}
+