]> granicus.if.org Git - clang/commitdiff
Delay semantic analysis of the C++ names casts when the subexpression is type-depende...
authorDouglas Gregor <dgregor@apple.com>
Wed, 17 Dec 2008 22:52:20 +0000 (22:52 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 17 Dec 2008 22:52:20 +0000 (22:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61165 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaNamedCast.cpp
test/SemaCXX/type-dependent-exprs.cpp

index 57c9763f7d2bb00e0b8a219d81fdfbee595f0e7b..d3bf1b96d641c620951597c6b9b7eceeb8c83734 100644 (file)
@@ -555,7 +555,10 @@ private:
 public:  
 
   UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
-    : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
+    : Expr(UnaryOperatorClass, type,
+           input->isTypeDependent() && opc != OffsetOf,
+           input->isValueDependent()), 
+      Val(input), Opc(opc), Loc(l) {}
 
   Opcode getOpcode() const { return Opc; }
   Expr *getSubExpr() const { return cast<Expr>(Val); }
index 515169c557e419624bb3d2d0b807335a8f2e4a4b..096bcbe37b09d94d2463d37cba1612f29afac252 100644 (file)
@@ -2876,6 +2876,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
 /// In C++, the operand might be an overloaded function name, in which case 
 /// we allow the '&' but retain the overloaded-function type.
 QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
+  if (op->isTypeDependent())
+    return Context.DependentTy;
+
   if (getLangOptions().C99) {
     // Implement C99-only parts of addressof rules.
     if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
index af1e2e000881ba6b669454eb68fae89578b3e1fe..3d3572d00ce4835f592d292ebd8fcfb6acf333cc 100644 (file)
@@ -65,26 +65,34 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
   SourceRange OpRange(OpLoc, RParenLoc);
   SourceRange DestRange(LAngleBracketLoc, RAngleBracketLoc);
 
+  // If the type is dependent, we won't do the semantic analysis now.
+  // FIXME: should we check this in a more fine-grained manner?
+  bool TypeDependent = DestType->isDependentType() || Ex->isTypeDependent();
+
   switch (Kind) {
   default: assert(0 && "Unknown C++ cast!");
 
   case tok::kw_const_cast:
-    CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
+    if (!TypeDependent)
+      CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
     return new CXXConstCastExpr(DestType.getNonReferenceType(), Ex, 
                                 DestType, OpLoc);
 
   case tok::kw_dynamic_cast:
-    CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange);
+    if (!TypeDependent)
+      CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange);
     return new CXXDynamicCastExpr(DestType.getNonReferenceType(), Ex, 
                                   DestType, OpLoc);
 
   case tok::kw_reinterpret_cast:
-    CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange);
+    if (!TypeDependent)
+      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange);
     return new CXXReinterpretCastExpr(DestType.getNonReferenceType(), Ex, 
                                       DestType, OpLoc);
 
   case tok::kw_static_cast:
-    CheckStaticCast(*this, Ex, DestType, OpRange);
+    if (!TypeDependent)
+      CheckStaticCast(*this, Ex, DestType, OpRange);
     return new CXXStaticCastExpr(DestType.getNonReferenceType(), Ex, 
                                  DestType, OpLoc);
   }
index 8d71073a0c22e5a5dc6ee9e94947d5153ce9b852..15808c676964ee0fa0938ee9322af63eee894a92 100644 (file)
@@ -1,4 +1,8 @@
 // RUN: clang -fsyntax-only -verify %s
+class X { 
+public:
+  virtual int f();
+};
 
 void g(int);
 
@@ -8,6 +12,10 @@ T f(T x) {
   (void)T(0);
   (void)(x += 0);
   (void)(x? x : x);
+  (void)static_cast<int>(x);
+  (void)reinterpret_cast<int>(x);
+  (void)dynamic_cast<X*>(&x);
+  (void)const_cast<int>(x);
   return g(x);
   h(x); // h is a dependent name
   g(1, 1); // expected-error{{too many arguments to function call}}