[cfe-commits] r159896 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp test/CodeGenCXX/cxx0x-initializer-constructors.cpp test/SemaCXX/constant-expression-cxx11.cpp test/SemaCXX/cxx0x-initializer-aggregate

Richard Smith richard at metafoo.co.uk
Sat Jul 7 16:05:06 PDT 2012


Thanks for the fix!

On Sat, Jul 7, 2012 at 2:26 AM, NAKAMURA Takumi <geek4civic at gmail.com>wrote:

> It seems broke -Asserts builds.
> 2012/07/07 17:37 "Richard Smith" <richard-llvm at metafoo.co.uk>:
>
>> Author: rsmith
>> Date: Sat Jul  7 03:35:56 2012
>> New Revision: 159896
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=159896&view=rev
>> Log:
>> PR12670: Support for initializing an array of non-aggregate class type
>> from an
>> initializer list. Patch by Olivier Goffart, with extra testcases by
>> Meador Inge
>> and Daniel Lunow.
>>
>> Added:
>>     cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
>>     cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp
>> Modified:
>>     cfe/trunk/lib/Sema/SemaInit.cpp
>>     cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>>     cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp
>>     cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp
>>
>> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=159896&r1=159895&r2=159896&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Jul  7 03:35:56 2012
>> @@ -687,22 +687,21 @@
>>    } else if (DeclType->isVectorType()) {
>>      CheckVectorType(Entity, IList, DeclType, Index,
>>                      StructuredList, StructuredIndex);
>> -  } else if (DeclType->isAggregateType()) {
>> -    if (DeclType->isRecordType()) {
>> -      RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
>> -      CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),
>> -                            SubobjectIsDesignatorContext, Index,
>> -                            StructuredList, StructuredIndex,
>> -                            TopLevelObject);
>> -    } else if (DeclType->isArrayType()) {
>> -      llvm::APSInt Zero(
>> -
>>  SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
>> -                      false);
>> -      CheckArrayType(Entity, IList, DeclType, Zero,
>> -                     SubobjectIsDesignatorContext, Index,
>> -                     StructuredList, StructuredIndex);
>> -    } else
>> -      llvm_unreachable("Aggregate that isn't a structure or array?!");
>> +  } else if (DeclType->isRecordType()) {
>> +    assert(DeclType->isAggregateType() &&
>> +           "non-aggregate records should be handed in
>> CheckSubElementType");
>> +    RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
>> +    CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),
>> +                          SubobjectIsDesignatorContext, Index,
>> +                          StructuredList, StructuredIndex,
>> +                          TopLevelObject);
>> +  } else if (DeclType->isArrayType()) {
>> +    llvm::APSInt Zero(
>> +
>>  SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
>> +                    false);
>> +    CheckArrayType(Entity, IList, DeclType, Zero,
>> +                   SubobjectIsDesignatorContext, Index,
>> +                   StructuredList, StructuredIndex);
>>    } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
>>      // This type is invalid, issue a diagnostic.
>>      ++Index;
>> @@ -710,19 +709,6 @@
>>        SemaRef.Diag(IList->getLocStart(),
>> diag::err_illegal_initializer_type)
>>          << DeclType;
>>      hadError = true;
>> -  } else if (DeclType->isRecordType()) {
>> -    // C++ [dcl.init]p14:
>> -    //   [...] If the class is an aggregate (8.5.1), and the initializer
>> -    //   is a brace-enclosed list, see 8.5.1.
>> -    //
>> -    // Note: 8.5.1 is handled below; here, we diagnose the case where
>> -    // we have an initializer list and a destination type that is not
>> -    // an aggregate.
>> -    // FIXME: In C++0x, this is yet another form of initialization.
>> -    if (!VerifyOnly)
>> -      SemaRef.Diag(IList->getLocStart(),
>> diag::err_init_non_aggr_init_list)
>> -        << DeclType << IList->getSourceRange();
>> -    hadError = true;
>>    } else if (DeclType->isReferenceType()) {
>>      CheckReferenceType(Entity, IList, DeclType, Index,
>>                         StructuredList, StructuredIndex);
>> @@ -747,18 +733,25 @@
>>                                            unsigned &StructuredIndex) {
>>    Expr *expr = IList->getInit(Index);
>>    if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
>> -    unsigned newIndex = 0;
>> -    unsigned newStructuredIndex = 0;
>> -    InitListExpr *newStructuredList
>> -      = getStructuredSubobjectInit(IList, Index, ElemType,
>> -                                   StructuredList, StructuredIndex,
>> -                                   SubInitList->getSourceRange());
>> -    CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,
>> -                          newStructuredList, newStructuredIndex);
>> -    ++StructuredIndex;
>> -    ++Index;
>> -    return;
>> -  } else if (ElemType->isScalarType()) {
>> +    if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
>> +      unsigned newIndex = 0;
>> +      unsigned newStructuredIndex = 0;
>> +      InitListExpr *newStructuredList
>> +        = getStructuredSubobjectInit(IList, Index, ElemType,
>> +                                     StructuredList, StructuredIndex,
>> +                                     SubInitList->getSourceRange());
>> +      CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,
>> +                            newStructuredList, newStructuredIndex);
>> +      ++StructuredIndex;
>> +      ++Index;
>> +      return;
>> +    }
>> +    assert(SemaRef.getLangOpts().CPlusPlus &&
>> +           "non-aggregate records are only possible in C++");
>> +    // C++ initialization is handled later.
>> +  }
>> +
>> +  if (ElemType->isScalarType()) {
>>      return CheckScalarType(Entity, IList, ElemType, Index,
>>                             StructuredList, StructuredIndex);
>>    } else if (ElemType->isReferenceType()) {
>>
>> Added: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=159896&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp (added)
>> +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp Sat Jul
>>  7 03:35:56 2012
>> @@ -0,0 +1,113 @@
>> +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
>> +
>> +namespace std {
>> +  typedef decltype(sizeof(int)) size_t;
>> +
>> +  template <typename E>
>> +  struct initializer_list
>> +  {
>> +    const E *p;
>> +    size_t n;
>> +    initializer_list(const E *p, size_t n) : p(p), n(n) {}
>> +  };
>> +
>> +  struct string {
>> +    string(const char *);
>> +  };
>> +
>> +  template<typename A, typename B>
>> +  struct pair {
>> +    pair(const A&, const B&);
>> +  };
>> +}
>> +
>> +namespace bullet2 {
>> +  double ad[] = { 1, 2.0 };
>> +  int ai[] = { 1, 2.0 };  // expected-error {{type 'double' cannot be
>> narrowed to 'int' in initializer list}} expected-note {{override}}
>> +
>> +  struct S2 {
>> +    int m1;
>> +    double m2, m3;
>> +  };
>> +
>> +  S2 s21 = { 1, 2, 3.0 };
>> +  S2 s22 { 1.0, 2, 3 };  // expected-error {{type 'double' cannot be
>> narrowed to 'int' in initializer list}} expected-note {{override}}
>> +  S2 s23 { };
>> +}
>> +
>> +namespace bullet4_example1 {
>> +  struct S {
>> +    S(std::initializer_list<double> d) {}
>> +    S(std::initializer_list<int> i) {}
>> +    S() {}
>> +  };
>> +
>> +  S s1 = { 1.0, 2.0, 3.0 };
>> +  S s2 = { 1, 2, 3 };
>> +  S s3 = { };
>> +}
>> +
>> +namespace bullet4_example2 {
>> +  struct Map {
>> +    Map(std::initializer_list<std::pair<std::string,int>>) {}
>> +  };
>> +
>> +  Map ship = {{"Sophie",14}, {"Surprise",28}};
>> +}
>> +
>> +namespace bullet4_example3 {
>> +  struct S {
>> +    S(int, double, double) {}
>> +    S() {}
>> +  };
>> +
>> +  S s1 = { 1, 2, 3.0 };
>> +  // FIXME: This is an ill-formed narrowing initialization.
>> +  S s2 { 1.0, 2, 3 };
>> +  S s3 {};
>> +}
>> +
>> +namespace bullet5 {
>> +  struct S {
>> +    S(std::initializer_list<double>) {}
>> +    S(const std::string &) {}
>> +  };
>> +
>> +  const S& r1 = { 1, 2, 3.0 };
>> +  const S& r2 = { "Spinach" };
>> +  S& r3 = { 1, 2, 3 };  // expected-error {{non-const lvalue reference
>> to type 'bullet5::S' cannot bind to an initializer list temporary}}
>> +  const int& i1 = { 1 };
>> +  const int& i2 = { 1.1 };  // expected-error {{type 'double' cannot be
>> narrowed to 'int' in initializer list}} expected-note {{override}}
>> expected-warning {{implicit conversion}}
>> +  const int (&iar)[2] = { 1, 2 };
>> +}
>> +
>> +namespace bullet6 {
>> +  int x1 {2};
>> +  int x2 {2.0};  // expected-error {{type 'double' cannot be narrowed to
>> 'int' in initializer list}} expected-note {{override}}
>> +}
>> +
>> +namespace bullet7 {
>> +  int** pp {};
>> +}
>> +
>> +namespace bullet8 {
>> +  struct A { int i; int j; };
>> +  A a1 { 1, 2 };
>> +  A a2 { 1.2 };  // expected-error {{type 'double' cannot be narrowed to
>> 'int' in initializer list}} expected-note {{override}} expected-warning
>> {{implicit conversion}}
>> +
>> +  struct B {
>> +    B(std::initializer_list<int> i) {}
>> +  };
>> +  B b1 { 1, 2 };
>> +  B b2 { 1, 2.0 };
>> +
>> +  struct C {
>> +    C(int i, double j) {}
>> +  };
>> +  C c1 = { 1, 2.2 };
>> +  // FIXME: This is an ill-formed narrowing initialization.
>> +  C c2 = { 1.1, 2 };  // expected-warning {{implicit conversion}}
>> +
>> +  int j { 1 };
>> +  int k { };
>> +}
>>
>> Added: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp?rev=159896&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp (added)
>> +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp Sat Jul
>>  7 03:35:56 2012
>> @@ -0,0 +1,37 @@
>> +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
>> +
>> +struct S {
>> +  S(int x) { }
>> +  S(int x, double y, double z) { }
>> +};
>> +
>> +void fn1() {
>> +  // CHECK: define void @_Z3fn1v
>> +  S s { 1 };
>> +  // CHECK: alloca %struct.S, align 1
>> +  // CHECK: call void @_ZN1SC1Ei(%struct.S* %s, i32 1)
>> +}
>> +
>> +void fn2() {
>> +  // CHECK: define void @_Z3fn2v
>> +  S s { 1, 2.0, 3.0 };
>> +  // CHECK: alloca %struct.S, align 1
>> +  // CHECK: call void @_ZN1SC1Eidd(%struct.S* %s, i32 1, double
>> 2.000000e+00, double 3.000000e+00)
>> +}
>> +
>> +void fn3() {
>> +  // CHECK: define void @_Z3fn3v
>> +  S sa[] { { 1 }, { 2 }, { 3 } };
>> +  // CHECK: alloca [3 x %struct.S], align 1
>> +  // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.begin, i32 1)
>> +  // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.element, i32 2)
>> +  // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.element1, i32 3)
>> +}
>> +
>> +void fn4() {
>> +  // CHECK: define void @_Z3fn4v
>> +  S sa[] { { 1, 2.0, 3.0 }, { 4, 5.0, 6.0 } };
>> +  // CHECK: alloca [2 x %struct.S], align 1
>> +  // CHECK: call void @_ZN1SC1Eidd(%struct.S* %arrayinit.begin, i32 1,
>> double 2.000000e+00, double 3.000000e+00)
>> +  // CHECK: call void @_ZN1SC1Eidd(%struct.S* %arrayinit.element, i32 4,
>> double 5.000000e+00, double 6.000000e+00)
>> +}
>>
>> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=159896&r1=159895&r2=159896&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sat Jul  7
>> 03:35:56 2012
>> @@ -1318,3 +1318,15 @@
>>    // actually call it.
>>    static_assert(S{}.t == 0, "");
>>  }
>> +
>> +namespace PR12670 {
>> +  struct S {
>> +    constexpr S(int a0) : m(a0) {}
>> +    constexpr S() : m(6) {}
>> +    int m;
>> +  };
>> +  constexpr S x[3] = { {4}, 5 };
>> +  static_assert(x[0].m == 4, "");
>> +  static_assert(x[1].m == 5, "");
>> +  static_assert(x[2].m == 6, "");
>> +}
>>
>> 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=159896&r1=159895&r2=159896&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp Sat Jul  7
>> 03:35:56 2012
>> @@ -87,3 +87,32 @@
>>      (void)test4{{{1}}}; // expected-note {{in instantiation of template
>> class 'array_explicit_conversion::A<-1>' requested here}}
>>    }
>>  }
>> +
>> +namespace sub_constructor {
>> +  struct DefaultConstructor { // expected-note 2 {{not viable}}
>> +    DefaultConstructor(); // expected-note  {{not viable}}
>> +    int x;
>> +  };
>> +  struct NoDefaultConstructor1 { // expected-note 2 {{not viable}}
>> +    NoDefaultConstructor1(int); // expected-note {{not viable}}
>> +    int x;
>> +  };
>> +  struct NoDefaultConstructor2 {  // expected-note 4 {{not viable}}
>> +    NoDefaultConstructor2(int,int); // expected-note 2 {{not viable}}
>> +    int x;
>> +  };
>> +
>> +  struct Aggr {
>> +    DefaultConstructor a;
>> +    NoDefaultConstructor1 b;
>> +    NoDefaultConstructor2 c;
>> +  };
>> +
>> +  Aggr ok1 { {}, {0} , {0,0} };
>> +  Aggr ok2 = { {}, {0} , {0,0} };
>> +  Aggr too_many { {0} , {0} , {0,0} }; // expected-error {{no matching
>> constructor for initialization}}
>> +  Aggr too_few { {} , {0} , {0} }; // expected-error {{no matching
>> constructor for initialization}}
>> +  Aggr invalid { {} , {&ok1} , {0,0} }; // expected-error {{no matching
>> constructor for initialization}}
>> +  NoDefaultConstructor2 array_ok[] = { {0,0} , {0,1} };
>> +  NoDefaultConstructor2 array_error[] = { {0,0} , {0} }; //
>> expected-error {{no matching constructor for initialization}}
>> +}
>> \ No newline at end of file
>>
>> Modified: cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp?rev=159896&r1=159895&r2=159896&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp Sat Jul  7 03:35:56 2012
>> @@ -15,7 +15,7 @@
>>  };
>>  NonAggregate non_aggregate_test = { 1, 2 }; //
>> expected-error{{non-aggregate type 'NonAggregate' cannot be initialized
>> with an initializer list}}
>>
>> -NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; //
>> expected-error 2 {{initialization of non-aggregate type 'NonAggregate' with
>> an initializer list}}
>> +NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; //
>> expected-error 2 {{non-aggregate type 'NonAggregate' cannot be initialized
>> with an initializer list}}
>>
>>
>>  // C++ [dcl.init.aggr]p3
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120707/5222e83e/attachment.html>


More information about the cfe-commits mailing list