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(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(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) 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/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/www/cxx_dr_status.html =================================================================== --- clang/www/cxx_dr_status.html +++ clang/www/cxx_dr_status.html @@ -12307,7 +12307,7 @@ 2082 CD4 Referring to parameters in unevaluated operands of default arguments - Unknown + SVN 2083