Modified ArraySubscriptExpr to have accessors getLHS and getRHS in addition
to getBase and getIdx. getBase and getIdx now return a "normalized" view
of the expression (e.g., always "A[4]" instead of possibly "4[A]"). getLHS
and getRHS return the expressions with syntactic fidelity to the original
source code.
Also modified client code of ArraySubscriptExpr, including the AST dumper
and pretty printer, the return-stack value checker, and the LLVM code
generator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41180 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaChecking.cpp b/Sema/SemaChecking.cpp
index d699e1b..a1deb3d 100644
--- a/Sema/SemaChecking.cpp
+++ b/Sema/SemaChecking.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Basic/SourceManager.h"
@@ -499,9 +500,24 @@
return NULL;
}
- // TODO: C++ casts.
- case Stmt::CXXCastExprClass:
- return NULL;
+ // C++ casts. For dynamic casts, static casts, and const casts, we
+ // are always converting from a pointer-to-pointer, so we just blow
+ // through the cast. In the case the dynamic cast doesn't fail
+ // (and return NULL), we take the conservative route and report cases
+ // where we return the address of a stack variable. For Reinterpre
+ case Stmt::CXXCastExprClass: {
+ CXXCastExpr *C = cast<CXXCastExpr>(E);
+
+ if (C->getOpcode() == CXXCastExpr::ReinterpretCast) {
+ Expr *S = C->getSubExpr();
+ if (S->getType()->isPointerType())
+ return EvalAddr(S);
+ else
+ return NULL;
+ }
+ else
+ return EvalAddr(C->getSubExpr());
+ }
// Everything else: we simply don't reason about them.
default:
@@ -554,18 +570,7 @@
// Array subscripts are potential references to data on the stack. We
// retrieve the DeclRefExpr* for the array variable if it indeed
// has local storage.
- ArraySubscriptExpr *A = cast<ArraySubscriptExpr>(E);
-
- // The array access could be written A[4] or 4[A] (both are equivalent).
- // In the second case, the "base" is the offset and the "Idx" is
- // the base. We test for this case by seeing if the Base expression
- // has a pointer type.
- Expr* Base = A->getBase();
-
- if (Base->getType()->isPointerType())
- return EvalAddr(Base);
- else
- return EvalAddr(A->getIdx());
+ return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase());
}
case Stmt::ConditionalOperatorClass: {