[cfe-commits] r150343 - in /cfe/trunk: include/clang/Sema/Initialization.h lib/Sema/SemaCast.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/SemaCXX/cxx0x-initializer-aggregates.cpp test/SemaCXX/cxx0x-initializer-references.cpp test/SemaCXX/cxx0x-initializer-scalars.cpp test/SemaCXX/generalized-initializers.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Sun Feb 12 08:37:36 PST 2012


Author: cornedbee
Date: Sun Feb 12 10:37:36 2012
New Revision: 150343

URL: http://llvm.org/viewvc/llvm-project?rev=150343&view=rev
Log:
Change the way we store initialization kinds so that all direct inits can distinguish between list and parens form. This allows us to correctly diagnose the last test cases from litb.

Removed:
    cfe/trunk/test/SemaCXX/generalized-initializers.cpp
Modified:
    cfe/trunk/include/clang/Sema/Initialization.h
    cfe/trunk/lib/Sema/SemaCast.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp

Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Sun Feb 12 10:37:36 2012
@@ -334,30 +334,27 @@
   };
   
 private:
-  /// \brief The kind of initialization that we're storing.
-  enum StoredInitKind {
-    SIK_Direct = IK_Direct,         ///< Direct initialization
-    SIK_DirectList = IK_DirectList, ///< Direct list-initialization
-    SIK_Copy = IK_Copy,             ///< Copy initialization
-    SIK_Default = IK_Default,       ///< Default initialization
-    SIK_Value = IK_Value,           ///< Value initialization
-    SIK_ImplicitValue,              ///< Implicit value initialization
-    SIK_DirectCast,  ///< Direct initialization due to a cast
-    /// \brief Direct initialization due to a C-style cast.
-    SIK_DirectCStyleCast,
-    /// \brief Direct initialization due to a functional-style cast.
-    SIK_DirectFunctionalCast
+  /// \brief The context of the initialization.
+  enum InitContext {
+    IC_Normal,         ///< Normal context
+    IC_Implicit,       ///< Implicit context (value initialization)
+    IC_StaticCast,     ///< Static cast context
+    IC_CStyleCast,     ///< C-style cast context
+    IC_FunctionalCast  ///< Functional cast context
   };
   
   /// \brief The kind of initialization being performed.
-  StoredInitKind Kind;
+  InitKind Kind : 8;
+
+  /// \brief The context of the initialization.
+  InitContext Context : 8;
   
   /// \brief The source locations involved in the initialization.
   SourceLocation Locations[3];
   
-  InitializationKind(StoredInitKind Kind, SourceLocation Loc1, 
+  InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1, 
                      SourceLocation Loc2, SourceLocation Loc3)
-    : Kind(Kind) 
+    : Kind(Kind), Context(Context)
   {
     Locations[0] = Loc1;
     Locations[1] = Loc2;
@@ -369,45 +366,50 @@
   static InitializationKind CreateDirect(SourceLocation InitLoc,
                                          SourceLocation LParenLoc,
                                          SourceLocation RParenLoc) {
-    return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
+    return InitializationKind(IK_Direct, IC_Normal,
+                              InitLoc, LParenLoc, RParenLoc);
   }
 
   static InitializationKind CreateDirectList(SourceLocation InitLoc) {
-    return InitializationKind(SIK_DirectList, InitLoc, InitLoc, InitLoc);
+    return InitializationKind(IK_DirectList, IC_Normal,
+                              InitLoc, InitLoc, InitLoc);
   }
 
   /// \brief Create a direct initialization due to a cast that isn't a C-style 
   /// or functional cast.
   static InitializationKind CreateCast(SourceRange TypeRange) {
-    return InitializationKind(SIK_DirectCast,
-                              TypeRange.getBegin(), TypeRange.getBegin(), 
-                              TypeRange.getEnd());
+    return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
+                              TypeRange.getBegin(), TypeRange.getEnd());
   }
   
   /// \brief Create a direct initialization for a C-style cast.
   static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
-                                             SourceRange TypeRange) {
-    return InitializationKind(SIK_DirectCStyleCast,
-                              StartLoc, TypeRange.getBegin(), 
+                                             SourceRange TypeRange,
+                                             bool InitList) {
+    // C++ cast syntax doesn't permit init lists, but C compound literals are
+    // exactly that.
+    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+                              IC_CStyleCast, StartLoc, TypeRange.getBegin(),
                               TypeRange.getEnd());
   }
 
   /// \brief Create a direct initialization for a functional cast.
-  static InitializationKind CreateFunctionalCast(SourceRange TypeRange) {
-    return InitializationKind(SIK_DirectFunctionalCast,
-                              TypeRange.getBegin(), TypeRange.getBegin(), 
-                              TypeRange.getEnd());
+  static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
+                                                 bool InitList) {
+    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+                              IC_FunctionalCast, TypeRange.getBegin(),
+                              TypeRange.getBegin(), TypeRange.getEnd());
   }
 
   /// \brief Create a copy initialization.
   static InitializationKind CreateCopy(SourceLocation InitLoc,
                                        SourceLocation EqualLoc) {
-    return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
+    return InitializationKind(IK_Copy, IC_Normal, InitLoc, EqualLoc, EqualLoc);
   }
   
   /// \brief Create a default initialization.
   static InitializationKind CreateDefault(SourceLocation InitLoc) {
-    return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
+    return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
   }
   
   /// \brief Create a value initialization.
@@ -415,46 +417,39 @@
                                         SourceLocation LParenLoc,
                                         SourceLocation RParenLoc,
                                         bool isImplicit = false) {
-    return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value, 
+    return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
                               InitLoc, LParenLoc, RParenLoc);
   }
   
   /// \brief Determine the initialization kind.
   InitKind getKind() const {
-    if (Kind > SIK_ImplicitValue)
-      return IK_Direct;
-    if (Kind == SIK_ImplicitValue)
-      return IK_Value;
-
-    return (InitKind)Kind;
+    return Kind;
   }
   
   /// \brief Determine whether this initialization is an explicit cast.
   bool isExplicitCast() const {
-    return Kind == SIK_DirectCast || 
-           Kind == SIK_DirectCStyleCast ||
-           Kind == SIK_DirectFunctionalCast;
+    return Context >= IC_StaticCast;
   }
   
   /// \brief Determine whether this initialization is a C-style cast.
   bool isCStyleOrFunctionalCast() const { 
-    return Kind == SIK_DirectCStyleCast || Kind == SIK_DirectFunctionalCast; 
+    return Context >= IC_CStyleCast; 
   }
 
-  /// brief Determine whether this is a C-style cast.
+  /// \brief Determine whether this is a C-style cast.
   bool isCStyleCast() const {
-    return Kind == SIK_DirectCStyleCast;
+    return Context == IC_CStyleCast;
   }
 
-  /// brief Determine whether this is a functional-style cast.
+  /// \brief Determine whether this is a functional-style cast.
   bool isFunctionalCast() const {
-    return Kind == SIK_DirectFunctionalCast;
+    return Context == IC_FunctionalCast;
   }
 
   /// \brief Determine whether this initialization is an implicit
   /// value-initialization, e.g., as occurs during aggregate
   /// initialization.
-  bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
+  bool isImplicitValueInit() const { return Context == IC_Implicit; }
 
   /// \brief Retrieve the location at which initialization is occurring.
   SourceLocation getLocation() const { return Locations[0]; }
@@ -467,11 +462,11 @@
   /// \brief Retrieve the location of the equal sign for copy initialization
   /// (if present).
   SourceLocation getEqualLoc() const {
-    assert(Kind == SIK_Copy && "Only copy initialization has an '='");
+    assert(Kind == IK_Copy && "Only copy initialization has an '='");
     return Locations[1];
   }
 
-  bool isCopyInit() const { return Kind == SIK_Copy; }
+  bool isCopyInit() const { return Kind == IK_Copy; }
 
   /// \brief Retrieve whether this initialization allows the use of explicit
   ///        constructors.
@@ -480,7 +475,7 @@
   /// \brief Retrieve the source range containing the locations of the open
   /// and closing parentheses for value and direct initializations.
   SourceRange getParenRange() const {
-    assert((getKind() == IK_Direct || Kind == SIK_Value) &&
+    assert((Kind == IK_Direct || Kind == IK_Value) &&
            "Only direct- and value-initialization have parentheses");
     return SourceRange(Locations[1], Locations[2]);
   }

Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Sun Feb 12 10:37:36 2012
@@ -320,11 +320,13 @@
   if (!destType->isRecordType() && !srcType->isRecordType())
     return false;
 
+  bool initList = isa<InitListExpr>(src);
   InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
   InitializationKind initKind
     = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
-                                                              range)
-    : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range)
+                                                              range, initList)
+    : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
+                                                                      initList)
     : InitializationKind::CreateCast(/*type range?*/ range);
   InitializationSequence sequence(S, entity, initKind, &src, 1);
 
@@ -1301,13 +1303,16 @@
       return TC_Failed;
     }
   }
-  
+
+  // FIXME: doesn't correctly identify T({1})
+  bool InitList = isa<InitListExpr>(SrcExpr.get());
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
   InitializationKind InitKind
     = (CCK == Sema::CCK_CStyleCast)
-        ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange)
+        ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
+                                               InitList)
     : (CCK == Sema::CCK_FunctionalCast)
-        ? InitializationKind::CreateFunctionalCast(OpRange)
+        ? InitializationKind::CreateFunctionalCast(OpRange, InitList)
     : InitializationKind::CreateCast(OpRange);
   Expr *SrcExprRaw = SrcExpr.get();
   InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Feb 12 10:37:36 2012
@@ -2150,18 +2150,22 @@
     // any of the arguments are type-dependent expressions.
     DiscardCleanupsInEvaluationContext();
   } else {
+    bool InitList = false;
+    if (isa<InitListExpr>(Init)) {
+      InitList = true;
+      Args = &Init;
+      NumArgs = 1;
+    }
+
     // Initialize the member.
     InitializedEntity MemberEntity =
       DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
                    : InitializedEntity::InitializeMember(IndirectMember, 0);
     InitializationKind Kind =
-      InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
-                                       InitRange.getEnd());
+      InitList ? InitializationKind::CreateDirectList(IdLoc)
+               : InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
+                                                  InitRange.getEnd());
 
-    if (isa<InitListExpr>(Init)) {
-      Args = &Init;
-      NumArgs = 1;
-    }
     InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
     ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
                                             MultiExprArg(*this, Args, NumArgs),
@@ -2214,20 +2218,23 @@
       << TInfo->getTypeLoc().getLocalSourceRange();
   Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
 
-  SourceRange InitRange = Init->getSourceRange();
-  // Initialize the object.
-  InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
-                                     QualType(ClassDecl->getTypeForDecl(), 0));
-  InitializationKind Kind =
-    InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
-                                     InitRange.getEnd());
-
+  bool InitList = true;
   Expr **Args = &Init;
   unsigned NumArgs = 1;
   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    InitList = false;
     Args = ParenList->getExprs();
     NumArgs = ParenList->getNumExprs();
   }
+
+  SourceRange InitRange = Init->getSourceRange();
+  // Initialize the object.
+  InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
+                                     QualType(ClassDecl->getTypeForDecl(), 0));
+  InitializationKind Kind =
+    InitList ? InitializationKind::CreateDirectList(NameLoc)
+             : InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
+                                                InitRange.getEnd());
   InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
   ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
                                               MultiExprArg(*this, Args,NumArgs),
@@ -2341,18 +2348,21 @@
     BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
 
   // Initialize the base.
-  InitializedEntity BaseEntity =
-    InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
-  InitializationKind Kind = 
-    InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
-                                     InitRange.getEnd());
-
+  bool InitList = true;
   Expr **Args = &Init;
   unsigned NumArgs = 1;
   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    InitList = false;
     Args = ParenList->getExprs();
     NumArgs = ParenList->getNumExprs();
   }
+
+  InitializedEntity BaseEntity =
+    InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
+  InitializationKind Kind =
+    InitList ? InitializationKind::CreateDirectList(BaseLoc)
+             : InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
+                                                InitRange.getEnd());
   InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
   ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
                                           MultiExprArg(*this, Args, NumArgs),

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Feb 12 10:37:36 2012
@@ -3809,7 +3809,8 @@
     = InitializedEntity::InitializeTemporary(literalType);
   InitializationKind Kind
     = InitializationKind::CreateCStyleCast(LParenLoc, 
-                                           SourceRange(LParenLoc, RParenLoc));
+                                           SourceRange(LParenLoc, RParenLoc),
+                                           /*InitList=*/true);
   InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
                                        MultiExprArg(*this, &LiteralExpr, 1),

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Feb 12 10:37:36 2012
@@ -3970,11 +3970,13 @@
       SourceType = Initializer->getType();
   }
 
-  //     - If the initializer is a braced-init-list, the object is
-  //       list-initialized (8.5.4).
-  if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
-    TryListInitialization(S, Entity, Kind, InitList, *this);
-    return;
+  //     - If the initializer is a (non-parenthesized) braced-init-list, the
+  //       object is list-initialized (8.5.4).
+  if (Kind.getKind() != InitializationKind::IK_Direct) {
+    if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
+      TryListInitialization(S, Entity, Kind, InitList, *this);
+      return;
+    }
   }
 
   //     - If the destination type is a reference type, see 8.5.3.

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp Sun Feb 12 10:37:36 2012
@@ -56,4 +56,6 @@
     // String is not default-constructible
     static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload");
   }
+
+  struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{array initializer must be an initializer list}}
 }

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Sun Feb 12 10:37:36 2012
@@ -71,4 +71,9 @@
     static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
   }
 
+  void edge_cases() {
+    // FIXME: very poor error message
+    int const &b({0}); // expected-error {{could not bind}}
+  }
+
 }

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp?rev=150343&r1=150342&r2=150343&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp Sun Feb 12 10:37:36 2012
@@ -55,4 +55,9 @@
     emptylist({});
     emptylist({}, {}, {});
   }
+
+  void edge_cases() {
+    // FIXME: very poor error message
+    int a({0}); // expected-error {{cannot initialize}}
+  }
 }

Removed: cfe/trunk/test/SemaCXX/generalized-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/generalized-initializers.cpp?rev=150342&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/generalized-initializers.cpp (original)
+++ cfe/trunk/test/SemaCXX/generalized-initializers.cpp (removed)
@@ -1,52 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// XFAIL: *
-
-template <typename T, typename U>
-struct same_type { static const bool value = false; };
-template <typename T>
-struct same_type<T, T> { static const bool value = true; };
-
-namespace std {
-  typedef decltype(sizeof(int)) size_t;
-
-  // libc++'s implementation
-  template <class _E>
-  class initializer_list
-  {
-    const _E* __begin_;
-    size_t    __size_;
-
-    initializer_list(const _E* __b, size_t __s)
-      : __begin_(__b),
-        __size_(__s)
-    {}
-
-  public:
-    typedef _E        value_type;
-    typedef const _E& reference;
-    typedef const _E& const_reference;
-    typedef size_t    size_type;
-
-    typedef const _E* iterator;
-    typedef const _E* const_iterator;
-
-    initializer_list() : __begin_(nullptr), __size_(0) {}
-
-    size_t    size()  const {return __size_;}
-    const _E* begin() const {return __begin_;}
-    const _E* end()   const {return __begin_ + __size_;}
-  };
-}
-
-namespace litb {
-
-  // invalid
-  struct A { int a[2]; A():a({1, 2}) { } }; // expected-error {{}}
-
-  // invalid
-  int a({0}); // expected-error {{}}
-
-  // invalid
-  int const &b({0}); // expected-error {{}}
-
-}





More information about the cfe-commits mailing list