]> granicus.if.org Git - clang/commitdiff
Properly track l-paren of a CXXFucntionalCastExpr.
authorEli Friedman <eli.friedman@gmail.com>
Thu, 15 Aug 2013 22:02:56 +0000 (22:02 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 15 Aug 2013 22:02:56 +0000 (22:02 +0000)
In addition to storing more useful information in the AST, this
fixes a semantic check in template instantiation which checks whether
the l-paren location is valid.

Fixes PR16903.

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

include/clang/AST/ExprCXX.h
lib/AST/Expr.cpp
lib/AST/ExprCXX.cpp
lib/Analysis/ReachableCode.cpp
lib/Sema/SemaCast.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
test/SemaTemplate/instantiate-init.cpp

index 4a6cfae0681f8685a967c1289df056522db1ab0f..cf3b88bd2a9dc7f5b6d533a0315355e7d539cab8 100644 (file)
@@ -1206,17 +1206,16 @@ public:
 ///   x = int(0.5);
 /// \endcode
 class CXXFunctionalCastExpr : public ExplicitCastExpr {
-  SourceLocation TyBeginLoc;
+  SourceLocation LParenLoc;
   SourceLocation RParenLoc;
 
   CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
                         TypeSourceInfo *writtenTy,
-                        SourceLocation tyBeginLoc, CastKind kind,
-                        Expr *castExpr, unsigned pathSize,
-                        SourceLocation rParenLoc)
+                        CastKind kind, Expr *castExpr, unsigned pathSize,
+                        SourceLocation lParenLoc, SourceLocation rParenLoc)
     : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
                        castExpr, pathSize, writtenTy),
-      TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+      LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
 
   explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
     : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
@@ -1225,22 +1224,20 @@ public:
   static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
                                        ExprValueKind VK,
                                        TypeSourceInfo *Written,
-                                       SourceLocation TyBeginLoc,
                                        CastKind Kind, Expr *Op,
                                        const CXXCastPath *Path,
+                                       SourceLocation LPLoc,
                                        SourceLocation RPLoc);
   static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
                                             unsigned PathSize);
 
-  SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
-  void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
-  SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
-  SourceLocation getLocEnd() const LLVM_READONLY {
-    return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
-  }
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXFunctionalCastExprClass;
index 5c1a27da3658bde802e60aba9551baa4fbe38aaa..3eeb53e62016406ea7550eeb80e587c77213173a 100644 (file)
@@ -2177,7 +2177,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
     WarnE = this;
     if (const CXXFunctionalCastExpr *CXXCE =
             dyn_cast<CXXFunctionalCastExpr>(this)) {
-      Loc = CXXCE->getTypeBeginLoc();
+      Loc = CXXCE->getLocStart();
       R1 = CXXCE->getSubExpr()->getSourceRange();
     } else {
       const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
index 055fc3b8142b160c59093f9e55da34d323601c0f..0609eb1d65d678a127055ef42f94f66db477f0ef 100644 (file)
@@ -660,14 +660,14 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
 
 CXXFunctionalCastExpr *
 CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
-                              TypeSourceInfo *Written, SourceLocation L,
-                              CastKind K, Expr *Op, const CXXCastPath *BasePath,
-                               SourceLocation R) {
+                              TypeSourceInfo *Written, CastKind K, Expr *Op,
+                              const CXXCastPath *BasePath,
+                              SourceLocation L, SourceLocation R) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
   void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
                             + PathSize * sizeof(CXXBaseSpecifier*));
   CXXFunctionalCastExpr *E =
-    new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R);
+    new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -679,6 +679,14 @@ CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
   return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
 }
 
+SourceLocation CXXFunctionalCastExpr::getLocStart() const {
+  return getTypeInfoAsWritten()->getTypeLoc().getLocStart();
+}
+
+SourceLocation CXXFunctionalCastExpr::getLocEnd() const {
+  return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
+}
+
 UserDefinedLiteral::LiteralOperatorKind
 UserDefinedLiteral::getLiteralOperatorKind() const {
   if (getNumArgs() == 0)
index a90aebbe28edc1bff008cddf5152b4b71b4cb6ec..e15fe7d1266371203907af4caa4f5bb959513930 100644 (file)
@@ -227,7 +227,7 @@ static SourceLocation GetUnreachableLoc(const Stmt *S,
     case Expr::CXXFunctionalCastExprClass: {
       const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
       R1 = CE->getSubExpr()->getSourceRange();
-      return CE->getTypeBeginLoc();
+      return CE->getLocStart();
     }
     case Stmt::CXXTryStmtClass: {
       return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
index 888c14ec3924241782ef59b53ff6e9ad0fbd2539..e3227bcaefe9cba1a62c8106673ad7eccdf39171 100644 (file)
@@ -2364,6 +2364,6 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
     ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc));
 
   return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
-                         Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
-                         Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
+                         Op.ValueKind, CastTypeInfo, Op.Kind,
+                         Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
 }
index ee2eb6d02f6afffdc18be31d50d1694163d6ed71..0b58a3d86d8a55d35d81c08caf1ccdda41c98595 100644 (file)
@@ -902,8 +902,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
     InitListExpr *List = cast<InitListExpr>(Result.take());
     Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
                                     Expr::getValueKindForType(TInfo->getType()),
-                                                 TInfo, TyBeginLoc, CK_NoOp,
-                                                 List, /*Path=*/0, RParenLoc));
+                                                 TInfo, CK_NoOp, List,
+                                                 /*Path=*/0,
+                                                 LParenLoc, RParenLoc));
   }
 
   // FIXME: Improve AST representation?
index b3e8720f5e641124b060b7bdc8fa1d487d098664..9e5738394eae18e3a972193780f3230974028095 100644 (file)
@@ -7317,7 +7317,7 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
     return SemaRef.Owned(E);
 
   return getDerived().RebuildCXXFunctionalCastExpr(Type,
-                                      /*FIXME:*/E->getSubExpr()->getLocStart(),
+                                                   E->getLParenLoc(),
                                                    SubExpr.get(),
                                                    E->getRParenLoc());
 }
index c0193c37726c65385b573160299eea409d4de33d..eaea0f905cb72c209a5860175a372e6ef605aeaa 100644 (file)
@@ -1263,7 +1263,7 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
 
 void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
   VisitExplicitCastExpr(E);
-  E->setTypeBeginLoc(ReadSourceLocation(Record, Idx));
+  E->setLParenLoc(ReadSourceLocation(Record, Idx));
   E->setRParenLoc(ReadSourceLocation(Record, Idx));
 }
 
index 533496d5dc49c6106d3c4a32982ceb6e427b4298..95b96766875b273269865f23477c570f0cf7d919 100644 (file)
@@ -1226,7 +1226,7 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
 
 void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
   VisitExplicitCastExpr(E);
-  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getLParenLoc(), Record);
   Writer.AddSourceLocation(E->getRParenLoc(), Record);
   Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
 }
index 6a1a57ca659e5348572fbf43c45a48b8e6b9cd45..22c70be3a8dc0305ad097235d5b27904fd388325 100644 (file)
@@ -118,3 +118,18 @@ namespace PR13064 {
   template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
   C<A> c; // expected-note{{here}}
 }
+
+namespace PR16903 {
+  // Make sure we properly instantiate list-initialization.
+  template<typename T>
+  void fun (T it) {
+       int m = 0;
+       for (int i = 0; i < 4; ++i, ++it){
+               m |= long{char{*it}};
+       }
+  }
+  int test() {
+       char in[4] = {0,0,0,0};
+       fun(in);
+  }
+}