This revision was automatically updated to reflect the committed changes.
Closed by commit rG40ea01f6543d: [clang] Convert a default argument expression 
to the parameter type... (authored by riccibruno).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81616/new/

https://reviews.llvm.org/D81616

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
  clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
  clang/test/SemaCXX/vartemplate-lambda.cpp
  clang/test/SemaTemplate/instantiate-local-class.cpp

Index: clang/test/SemaTemplate/instantiate-local-class.cpp
===================================================================
--- clang/test/SemaTemplate/instantiate-local-class.cpp
+++ clang/test/SemaTemplate/instantiate-local-class.cpp
@@ -462,18 +462,15 @@
     struct Inner { // expected-note {{in instantiation}}
       void operator()(T a = "") {} // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
       // expected-note@-1 {{passing argument to parameter 'a' here}}
-      // expected-note@-2 {{candidate function not viable}}
     };
-    Inner()(); // expected-error {{no matching function}}
+    Inner()(); // expected-error {{type 'Inner' does not provide a call operator}}
   }
   template void foo<A>(); // expected-note 2 {{in instantiation}}
 
   template <typename T> void bar() {
     auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
       // expected-note@-1 {{passing argument to parameter 'a' here}}
-      // expected-note@-2 {{candidate function not viable}}
-      // expected-note@-3 {{conversion candidate of type}}
-    lambda(); // expected-error {{no matching function}}
+    lambda();
   }
   template void bar<A>(); // expected-note {{in instantiation}}
 }
@@ -494,9 +491,6 @@
   void f(int x = [](T x = nullptr) -> int { return x; }());
   // expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'nullptr_t'}}
   // expected-note@-2 {{passing argument to parameter 'x' here}}
-  // expected-error@-3 {{no matching function for call}}
-  // expected-note@-4 {{candidate function not viable: requires single argument 'x', but no arguments were provided}}
-  // expected-note@-5 {{conversion candidate of type 'auto (*)(int) -> int'}}
 
   void g() { f<int>(); }
   // expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}}
Index: clang/test/SemaCXX/vartemplate-lambda.cpp
===================================================================
--- clang/test/SemaCXX/vartemplate-lambda.cpp
+++ clang/test/SemaCXX/vartemplate-lambda.cpp
@@ -6,10 +6,7 @@
 template<typename T> auto fn1 = [](auto a) { return a + T(1); };
 template<typename T> auto v1 = [](int a = T()) { return a; }();
 // expected-error@-1{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}}
-// expected-error@-2{{no matching function for call}}
-// expected-note@-3{{passing argument to parameter 'a' here}}
-// expected-note@-4{{candidate function not viable}}
-// expected-note@-5{{conversion candidate of type 'int (*)(int)'}}
+// expected-note@-2{{passing argument to parameter 'a' here}}
 
 struct S {
   template<class T>
Index: clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
+++ clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p8.cpp
@@ -6,5 +6,10 @@
 };
 
 void A::test() {
-  void g(int = this); // expected-error {{default argument references 'this'}}
+  void g(int = this);
+  // expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'A *'}}
+  // expected-note@-2 {{passing argument to parameter here}}
+
+  void h(int = ((void)this,42));
+  // expected-error@-1 {{default argument references 'this'}}
 }
Index: clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
+++ clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
@@ -6,8 +6,7 @@
   // expected-error@-1 {{default argument references local variable 'i1' of enclosing function}}
 
   const int i2 = 0;
-  extern void h2a(int x = i2); // FIXME: ok, not odr-use
-  // expected-error@-1 {{default argument references local variable 'i2' of enclosing function}}
+  extern void h2a(int x = i2);     // ok, not odr-use
   extern void h2b(int x = i2 + 0); // ok, not odr-use
 
   const int i3 = 0;
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2405,7 +2405,12 @@
       if (NewArg.isUsable()) {
         // It would be nice if we still had this.
         SourceLocation EqualLoc = NewArg.get()->getBeginLoc();
-        SetParamDefaultArgument(NewParm, NewArg.get(), EqualLoc);
+        ExprResult Result =
+            ConvertParamDefaultArgument(NewParm, NewArg.get(), EqualLoc);
+        if (Result.isInvalid())
+          return nullptr;
+
+        SetParamDefaultArgument(NewParm, Result.getAs<Expr>(), EqualLoc);
       }
     } else {
       // FIXME: if we non-lazily instantiated non-dependent default args for
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -254,14 +254,12 @@
     ComputedEST = EST_None;
 }
 
-bool
-Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
-                              SourceLocation EqualLoc) {
+ExprResult Sema::ConvertParamDefaultArgument(const ParmVarDecl *Param,
+                                             Expr *Arg,
+                                             SourceLocation EqualLoc) {
   if (RequireCompleteType(Param->getLocation(), Param->getType(),
-                          diag::err_typecheck_decl_incomplete_type)) {
-    Param->setInvalidDecl();
+                          diag::err_typecheck_decl_incomplete_type))
     return true;
-  }
 
   // C++ [dcl.fct.default]p5
   //   A default argument expression is implicitly converted (clause
@@ -282,7 +280,12 @@
   CheckCompletedExpr(Arg, EqualLoc);
   Arg = MaybeCreateExprWithCleanups(Arg);
 
-  // Okay: add the default argument to the parameter
+  return Arg;
+}
+
+void Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
+                                   SourceLocation EqualLoc) {
+  // Add the default argument to the parameter
   Param->setDefaultArg(Arg);
 
   // We have already instantiated this parameter; provide each of the
@@ -296,8 +299,6 @@
     // We're done tracking this parameter's instantiations.
     UnparsedDefaultArgInstantiations.erase(InstPos);
   }
-
-  return false;
 }
 
 /// ActOnParamDefaultArgument - Check whether the default argument
@@ -341,13 +342,18 @@
     return;
   }
 
+  ExprResult Result = ConvertParamDefaultArgument(Param, DefaultArg, EqualLoc);
+  if (Result.isInvalid())
+    return Fail();
+
+  DefaultArg = Result.getAs<Expr>();
+
   // Check that the default argument is well-formed
   CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg);
   if (DefaultArgChecker.Visit(DefaultArg))
     return Fail();
 
-  if (SetParamDefaultArgument(Param, DefaultArg, EqualLoc))
-    return Fail();
+  SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
 }
 
 /// ActOnParamUnparsedDefaultArgument - We've seen a default
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2381,11 +2381,13 @@
   void ActOnParamDefaultArgument(Decl *param,
                                  SourceLocation EqualLoc,
                                  Expr *defarg);
-  void ActOnParamUnparsedDefaultArgument(Decl *param,
-                                         SourceLocation EqualLoc,
+  void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc,
                                          SourceLocation ArgLoc);
   void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
-  bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
+  ExprResult ConvertParamDefaultArgument(const ParmVarDecl *Param,
+                                         Expr *DefaultArg,
+                                         SourceLocation EqualLoc);
+  void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
                                SourceLocation EqualLoc);
 
   // Contexts where using non-trivial C union types can be disallowed. This is
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to