[PATCH] D25719: [Sema] Fix PR30664

2016-10-27 Thread Richard Smith via cfe-commits
rsmith added inline comments.



Comment at: lib/Sema/SemaExprCXX.cpp:3429-3430
   // initial standard conversion sequence converts the source type to
-  // the type required by the argument of the constructor
-  BeforeToType = 
Ctor->getParamDecl(0)->getType().getNonReferenceType();
+  // the type required by the argument of the constructor or the 'void'
+  // type if the argument has no constructors.
+  BeforeToType =

I think you mean "if the constructor has no parameters", right?



Comment at: lib/Sema/SemaExprCXX.cpp:3433
+  Ctor->param_empty()
+  ? Context.VoidTy
+  : Ctor->getParamDecl(0)->getType().getNonReferenceType();

It looks like this will result in us building an expression like `T(void({}))`. 
That would be invalid, and we shouldn't have it in the AST. Instead, we should 
probably build `T{}` for this case.



Comment at: test/SemaCXX/cxx11-crashes.cpp:109
+const outer // expected-note {{reference member declared here}}
+inner() : o({}) {} // expected-warning {{binding reference member 'o' to a 
temporary value}}
+  };

This case is ill-formed under 
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1696

Is there any way to tickle this problem without binding a class member to a 
temporary? If not, I'd prefer we instead implement DR1696 to eliminate the 
problem.


Repository:
  rL LLVM

https://reviews.llvm.org/D25719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25719: [Sema] Fix PR30664

2016-10-18 Thread Alex Lorenz via cfe-commits
arphaman created this revision.
arphaman added a reviewer: rsmith.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch fixes an assertion failure crash that happens when a constant record 
reference member is initialized using an empty initializer list.


Repository:
  rL LLVM

https://reviews.llvm.org/D25719

Files:
  lib/Sema/SemaExprCXX.cpp
  test/SemaCXX/cxx11-crashes.cpp


Index: test/SemaCXX/cxx11-crashes.cpp
===
--- test/SemaCXX/cxx11-crashes.cpp
+++ test/SemaCXX/cxx11-crashes.cpp
@@ -91,3 +91,33 @@
   Foo(lambda);
 }
 }
+
+namespace pr30664 {
+struct foo {
+  int x;
+  foo() : x(42) { }
+};
+
+struct bar {
+  const foo   // expected-note {{reference member declared here}}
+  bar() : o{} {} // expected-warning {{binding reference member 'o' to a 
temporary value}}
+};
+
+struct outer {
+  struct inner {
+const outer // expected-note {{reference member declared here}}
+inner() : o({}) {} // expected-warning {{binding reference member 'o' to a 
temporary value}}
+  };
+};
+
+outer::inner i;
+
+struct foobar {
+  foobar(void) { }
+  struct inner {
+int y;
+const foobar  // expected-note {{reference member declared here}}
+inner() : y(21), o({}) {} // expected-warning {{binding reference member 
'o' to a temporary value}}
+  };
+};
+}
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -3426,8 +3426,12 @@
 if (!ICS.UserDefined.EllipsisConversion) {
   // If the user-defined conversion is specified by a constructor, the
   // initial standard conversion sequence converts the source type to
-  // the type required by the argument of the constructor
-  BeforeToType = 
Ctor->getParamDecl(0)->getType().getNonReferenceType();
+  // the type required by the argument of the constructor or the 'void'
+  // type if the argument has no constructors.
+  BeforeToType =
+  Ctor->param_empty()
+  ? Context.VoidTy
+  : Ctor->getParamDecl(0)->getType().getNonReferenceType();
 }
   }
   // Watch out for ellipsis conversion.


Index: test/SemaCXX/cxx11-crashes.cpp
===
--- test/SemaCXX/cxx11-crashes.cpp
+++ test/SemaCXX/cxx11-crashes.cpp
@@ -91,3 +91,33 @@
   Foo(lambda);
 }
 }
+
+namespace pr30664 {
+struct foo {
+  int x;
+  foo() : x(42) { }
+};
+
+struct bar {
+  const foo   // expected-note {{reference member declared here}}
+  bar() : o{} {} // expected-warning {{binding reference member 'o' to a temporary value}}
+};
+
+struct outer {
+  struct inner {
+const outer // expected-note {{reference member declared here}}
+inner() : o({}) {} // expected-warning {{binding reference member 'o' to a temporary value}}
+  };
+};
+
+outer::inner i;
+
+struct foobar {
+  foobar(void) { }
+  struct inner {
+int y;
+const foobar  // expected-note {{reference member declared here}}
+inner() : y(21), o({}) {} // expected-warning {{binding reference member 'o' to a temporary value}}
+  };
+};
+}
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -3426,8 +3426,12 @@
 if (!ICS.UserDefined.EllipsisConversion) {
   // If the user-defined conversion is specified by a constructor, the
   // initial standard conversion sequence converts the source type to
-  // the type required by the argument of the constructor
-  BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType();
+  // the type required by the argument of the constructor or the 'void'
+  // type if the argument has no constructors.
+  BeforeToType =
+  Ctor->param_empty()
+  ? Context.VoidTy
+  : Ctor->getParamDecl(0)->getType().getNonReferenceType();
 }
   }
   // Watch out for ellipsis conversion.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits