Prevent Clang from crashing on template code.
authorRichard Trieu <rtrieu@google.com>
Wed, 2 Jul 2014 04:39:38 +0000 (04:39 +0000)
committerRichard Trieu <rtrieu@google.com>
Wed, 2 Jul 2014 04:39:38 +0000 (04:39 +0000)
Fixes PR20110, where Clang hits an assertion failure when it expects that the
sub-expression of a bit cast to pointer to also be a pointer, but gets a value
instead.

Differential Revision: http://reviews.llvm.org/D4280

llvm-svn: 212160

clang/lib/Sema/SemaChecking.cpp
clang/test/SemaCXX/PR20110.cpp [new file with mode: 0644]

index 1a49b4a..cd31f72 100644 (file)
@@ -4613,7 +4613,6 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars,
   case Stmt::CXXReinterpretCastExprClass: {
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     switch (cast<CastExpr>(E)->getCastKind()) {
-    case CK_BitCast:
     case CK_LValueToRValue:
     case CK_NoOp:
     case CK_BaseToDerived:
@@ -4628,6 +4627,14 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars,
     case CK_ArrayToPointerDecay:
       return EvalVal(SubExpr, refVars, ParentDecl);
 
+    case CK_BitCast:
+      if (SubExpr->getType()->isAnyPointerType() ||
+          SubExpr->getType()->isBlockPointerType() ||
+          SubExpr->getType()->isObjCQualifiedIdType())
+        return EvalAddr(SubExpr, refVars, ParentDecl);
+      else
+        return nullptr;
+
     default:
       return nullptr;
     }
diff --git a/clang/test/SemaCXX/PR20110.cpp b/clang/test/SemaCXX/PR20110.cpp
new file mode 100644 (file)
index 0000000..e540a73
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+// FIXME: These templates should trigger errors in C++11 mode.
+
+template <char const *p>
+class A {
+  char const *get_p() { return *p; }
+};
+template <int p>
+class B {
+  char const *get_p() { return p; }
+};
+