diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12977,6 +12977,10 @@ }); } + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *DAE) { + Visit(DAE->getExpr()); + } + void VisitCXXConstructExpr(const CXXConstructExpr *CCE) { // This is a call, so all subexpressions are sequenced before the result. SequencedSubexpression Sequenced(*this); diff --git a/clang/test/SemaCXX/warn-unsequenced.cpp b/clang/test/SemaCXX/warn-unsequenced.cpp --- a/clang/test/SemaCXX/warn-unsequenced.cpp +++ b/clang/test/SemaCXX/warn-unsequenced.cpp @@ -268,6 +268,36 @@ // cxx17-warning@-1 {{unsequenced modification and access to 'pf'}} } +namespace default_arg { + int a; + void f1(int = a, int = a++); // cxx11-warning 2{{unsequenced modification and access to 'a'}} + // cxx17-warning@-1 2{{unsequenced modification and access to 'a'}} + + void f2(int = a++, int = a); // cxx11-warning {{unsequenced modification and access to 'a'}} + // cxx17-warning@-1 {{unsequenced modification and access to 'a'}} + + void f3(int = a++, int = sizeof(a)); + + void test() { + // TODO: Consider adding a remark indicating the function call where + // the default argument was used. + int b; + f1(); + f1(a); + f1(a,a); // ok + f1(b); // ok + f1(b,a++); // ok + + f2(); + f2(a); // ok + f2(a++); // cxx11-warning {{unsequenced modification and access to 'a'}} + // cxx17-warning@-1 {{unsequenced modification and access to 'a'}} + + f3(); // ok + f3(a++); // ok + } +} + namespace PR20819 { struct foo { void bar(int); }; foo get_foo(int);