r262966 - Fix crash in access check for aggregate initialization of base classes. It's

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 8 15:17:36 PST 2016


Author: rsmith
Date: Tue Mar  8 17:17:35 2016
New Revision: 262966

URL: http://llvm.org/viewvc/llvm-project?rev=262966&view=rev
Log:
Fix crash in access check for aggregate initialization of base classes. It's
not obvious how to access-check these, so pick a conservative rule until we get
feedback from CWG.

Modified:
    cfe/trunk/lib/Sema/SemaAccess.cpp
    cfe/trunk/test/SemaCXX/aggregate-initialization.cpp

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=262966&r1=262965&r2=262966&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Tue Mar  8 17:17:35 2016
@@ -1670,8 +1670,12 @@ Sema::AccessResult Sema::CheckConstructo
   // Initializing a base sub-object is an instance method call on an
   // object of the derived class.  Otherwise, we have an instance method
   // call on an object of the constructed type.
+  //
+  // FIXME: If we have a parent, we're initializing the base class subobject
+  // in aggregate initialization. It's not clear whether the object class
+  // should be the base class or the derived class in that case.
   CXXRecordDecl *ObjectClass;
-  if (Entity.getKind() == InitializedEntity::EK_Base) {
+  if (Entity.getKind() == InitializedEntity::EK_Base && !Entity.getParent()) {
     ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
   } else {
     ObjectClass = NamingClass;

Modified: cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?rev=262966&r1=262965&r2=262966&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/aggregate-initialization.cpp (original)
+++ cfe/trunk/test/SemaCXX/aggregate-initialization.cpp Tue Mar  8 17:17:35 2016
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s 
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s 
 
 // Verify that using an initializer list for a non-aggregate looks for
 // constructors..
@@ -11,7 +13,7 @@ struct NonAggr1 { // expected-note 2 {{c
 };
 
 struct Base { };
-struct NonAggr2 : public Base { // expected-note 3 {{candidate constructor}}
+struct NonAggr2 : public Base { // expected-note 0-3 {{candidate constructor}}
   int m;
 };
 
@@ -25,9 +27,15 @@ struct NonAggr4 { // expected-note 3 {{c
 };
 
 NonAggr1 na1 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr1'}}
-NonAggr2 na2 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr2'}}
+NonAggr2 na2 = { 17 };
 NonAggr3 na3 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr3'}}
 NonAggr4 na4 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr4'}}
+#if __cplusplus <= 201402L
+// expected-error at -4{{no matching constructor for initialization of 'NonAggr2'}}
+#else
+// expected-error at -6{{requires explicit braces}}
+NonAggr2 na2b = { {}, 17 }; // ok
+#endif
 
 // PR5817
 typedef int type[][2];
@@ -82,3 +90,59 @@ public:
 };
 
 AggAgg aggagg = { 1, 2, 3, 4 };
+
+namespace diff_cpp14_dcl_init_aggr_example {
+  struct derived;
+  struct base {
+    friend struct derived;
+  private:
+    base();
+  };
+  struct derived : base {};
+
+  derived d1{};
+#if __cplusplus > 201402L
+  // expected-error at -2 {{private}}
+  // expected-note at -7 {{here}}
+#endif
+  derived d2;
+}
+
+namespace ProtectedBaseCtor {
+  // FIXME: It's unclear whether f() and g() should be valid in C++1z. What is
+  // the object expression in a constructor call -- the base class subobject or
+  // the complete object?
+  struct A {
+  protected:
+    A();
+  };
+
+  struct B : public A {
+    friend B f();
+    friend B g();
+    friend B h();
+  };
+
+  B f() { return {}; }
+#if __cplusplus > 201402L
+  // expected-error at -2 {{protected default constructor}}
+  // expected-note at -12 {{here}}
+#endif
+
+  B g() { return {{}}; }
+#if __cplusplus <= 201402L
+  // expected-error at -2 {{no matching constructor}}
+  // expected-note at -15 3{{candidate}}
+#else
+  // expected-error at -5 {{protected default constructor}}
+  // expected-note at -21 {{here}}
+#endif
+
+  B h() { return {A{}}; }
+#if __cplusplus <= 201402L
+  // expected-error at -2 {{no matching constructor}}
+  // expected-note at -24 3{{candidate}}
+#endif
+  // expected-error at -5 {{protected constructor}}
+  // expected-note at -30 {{here}}
+}




More information about the cfe-commits mailing list