From e99046b20f3965391fc16ff67037745b7d315e45 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Mon, 15 Feb 2016 01:51:24 +0000 Subject: [PATCH] Sema: prevent assertion on stack return checking 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 | 6 ++++-- test/SemaCXX/return-stack-addr-2.cpp | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 test/SemaCXX/return-stack-addr-2.cpp diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 227079f342..db29e72005 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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(E)->getBase(), refVars, - ParentDecl); + const auto *ASE = cast(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 index 0000000000..ad27567fcd --- /dev/null +++ b/test/SemaCXX/return-stack-addr-2.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics + +namespace PR26599 { +template +struct S; + +struct I {}; + +template +void *&non_pointer() { + void *&r = S()[I{}]; + return r; +} + +template +void *&pointer() { + void *&r = S()[nullptr]; + return r; +} +} + -- 2.40.0