[PATCH] D65696: Implements CWG 2082 Referring to parameters in unevaluated operands of default arguments

Mark de Wever via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 3 03:46:22 PDT 2019


Mordante created this revision.
Mordante added a reviewer: rsmith.
Mordante added a project: clang.

This implements the current standard wording for [dcl.fct.default]p9 and [dcl.fct.default]p7. This has been changed by CWG 2082.

      

Note: I don't have access to the paper therefore I assume it retroactively applies to all C++ standards.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D65696

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p9.cpp
  clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
  clang/www/cxx_dr_status.html


Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -12307,7 +12307,7 @@
     <td><a href="http://wg21.link/cwg2082">2082</a></td>
     <td>CD4</td>
     <td>Referring to parameters in unevaluated operands of default arguments</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="2083">
     <td><a href="http://wg21.link/cwg2083">2083</a></td>
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
@@ -1,7 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-void h()
+void f()
 {
   int i;
-  extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}}
+  extern void g(int x = i); // expected-error {{default argument references local variable 'i' of enclosing function}}
+  extern void h(int x = sizeof(i));
 }
Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p9.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p9.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int a;
+int f(int a, int b = a); // expected-error {{default argument references parameter 'a'}}
+typedef int I;
+int g(float I, int b = I(2)); // expected-error {{called object type 'float' is not a function or function pointer}}
+int h(int a, int b = sizeof(a));
+
+int b;
+class X {
+  int a;
+  int mem1(int i = a); // expected-error {{invalid use of non-static data member 'a'}}
+  int mem2(int i = b);
+  static int b;
+};
+
+int f(int = 0);
+void h() {
+  int j = f(1);
+  int k = f();
+}
+int (*p1)(int) = &f;
+int (*p2)() = &f; // expected-error {{cannot initialize a variable of type 'int (*)()' with an rvalue of type 'int (*)(int)': different number of parameters (0 vs 1)}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -86,20 +86,24 @@
     NamedDecl *Decl = DRE->getDecl();
     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) {
       // C++ [dcl.fct.default]p9
-      //   Default arguments are evaluated each time the function is
-      //   called. The order of evaluation of function arguments is
-      //   unspecified. Consequently, parameters of a function shall not
-      //   be used in default argument expressions, even if they are not
-      //   evaluated. Parameters of a function declared before a default
-      //   argument expression are in scope and can hide namespace and
-      //   class member names.
+      //   A default argument is evaluated each time the function is called
+      //   with no argument for the corresponding parameter. A parameter shall
+      //   not appear as a potentially-evaluated expression in a default
+      //   argument. Parameters of a function declared before a default
+      //   argument are in scope and can hide namespace and class member
+      //   names.
+      if (DRE->isNonOdrUse() == NOUR_Unevaluated)
+        return false;
+
       return S->Diag(DRE->getBeginLoc(),
                      diag::err_param_default_argument_references_param)
              << Param->getDeclName() << DefaultArg->getSourceRange();
     } else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) {
       // C++ [dcl.fct.default]p7
-      //   Local variables shall not be used in default argument
-      //   expressions.
+      //   A local variable cannot be odr-used (6.2) in a default argument.
+      if (DRE->isNonOdrUse() != NOUR_None)
+        return false;
+
       if (VDecl->isLocalVarDecl())
         return S->Diag(DRE->getBeginLoc(),
                        diag::err_param_default_argument_references_local)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65696.213186.patch
Type: text/x-patch
Size: 4089 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190803/d29f71a5/attachment-0001.bin>


More information about the cfe-commits mailing list