]> granicus.if.org Git - clang/commitdiff
Fix PR20334: invalid assertion while diagnosing list initialization failure
authorFaisal Vali <faisalv@yahoo.com>
Mon, 7 Dec 2015 02:37:44 +0000 (02:37 +0000)
committerFaisal Vali <faisalv@yahoo.com>
Mon, 7 Dec 2015 02:37:44 +0000 (02:37 +0000)
https://llvm.org/bugs/show_bug.cgi?id=20334

Unfortunately, clang currently checks for a certain brokenness of implementations of std::initializer_list in CodeGen (void
AggExprEmitter::VisitCXXStdInitializerListExpr), not in SemaInit.  Until that is fixed, make sure we don't let broken attempts that are aggregates leak through into sema, which allows maintenance of expected invariants, and avoids triggering an assertion.

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

lib/Sema/SemaInit.cpp
test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp [new file with mode: 0644]

index 89d253981c5c9d4436a10f4a5d145bfa0c3a6ba1..0f60ad10a3e3398cfad995df05698eb52a28cc6b 100644 (file)
@@ -3732,7 +3732,9 @@ static void TryListInitialization(Sema &S,
 
   // C++11 [dcl.init.list]p3:
   //   - If T is an aggregate, aggregate initialization is performed.
-  if (DestType->isRecordType() && !DestType->isAggregateType()) {
+  if ((DestType->isRecordType() && !DestType->isAggregateType()) ||
+      (S.getLangOpts().CPlusPlus11 &&
+       S.isStdInitializerList(DestType, nullptr))) {
     if (S.getLangOpts().CPlusPlus11) {
       //   - Otherwise, if the initializer list has no elements and T is a
       //     class type with a default constructor, the object is
diff --git a/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp b/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp
new file mode 100644 (file)
index 0000000..ec67208
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 -verify -emit-llvm-only %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s -DCPP98
+
+namespace std {
+  template <class _E>
+  class initializer_list
+  {};
+}
+
+template<class E> int f(std::initializer_list<E> il);
+       
+
+int F = f({1, 2, 3});
+#ifdef CPP98
+//expected-error@-2{{expected expression}}
+#else
+//expected-error@-4{{cannot compile}}
+#endif
+
+