[PATCH] D158372: [Clang] Treat invalid UDL as two tokens

2023-08-22 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

OK, will do it by the end of this week.


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

https://reviews.llvm.org/D158372

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


[PATCH] D158372: [Clang] Treat invalid UDL as two tokens

2023-08-21 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added inline comments.



Comment at: clang/lib/Lex/Lexer.cpp:1994-2009
   if (!isAsciiIdentifierStart(C)) {
 if (C == '\\' && tryConsumeIdentifierUCN(CurPtr, Size, Result))
   Consumed = true;
 else if (!isASCII(C) && tryConsumeIdentifierUTF8Char(CurPtr))
   Consumed = true;
 else
   return CurPtr;

cor3ntin wrote:
> I missed that in the previous review, is the FIX-IT here still relevant?
Yes, I also put back the fixit test.


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

https://reviews.llvm.org/D158372

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


[PATCH] D158372: [Clang] Treat invalid UDL as two tokens

2023-08-21 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 552060.
rZhBoYao marked 5 inline comments as done.
rZhBoYao edited the summary of this revision.

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

https://reviews.llvm.org/D158372

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Lex/Lexer.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/FixIt/fixit-c++11.cpp

Index: clang/test/FixIt/fixit-c++11.cpp
===
--- clang/test/FixIt/fixit-c++11.cpp
+++ clang/test/FixIt/fixit-c++11.cpp
@@ -68,9 +68,9 @@
 }
 
 #define bar "bar"
-const char *p = "foo" bar;
+const char *p = "foo"bar; // expected-error {{requires a space between}}
 #define ord - '0'
-int k = '4' ord;
+int k = '4'ord; // expected-error {{requires a space between}}
 
 void operator"x" _y(char); // expected-error {{must be '""'}}
 void operator L"" _z(char); // expected-error {{encoding prefix}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator ""wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
-void operator ""wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator ""wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved}}
 
 template
 void f() {
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -141,9 +141,14 @@
 namespace dr1762 { // dr1762: 14
// NB: reusing 1473 test
 #if __cplusplus >= 201103L
-  float operator ""_E(const char *);
-  float operator ""E(const char *);
-  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+#define E "!"
+const char
+  *operator""_E(const char*),
+  *operator""E(const char*), // don't err on the lack of spaces even when the literal suffix identifier is invalid
+  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved}}
+  *s = "not empty"E;
+  // expected-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and a macro}}
+#undef E
 #endif
 }
 
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -487,9 +487,14 @@
 namespace dr1473 { // dr1473: 18
// NB: sup 1762, test reused there
 #if __cplusplus >= 201103L
-  float operator ""_E(const char *);
-  float operator ""E(const char *); // don't err on the lack of spaces even when the literal suffix identifier is invalid
-  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+#define E "!"
+const char
+  *operator""_E(const char*),
+  *operator""E(const char*), // don't err on the lack of spaces even when the literal suffix identifier is invalid
+  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved}}
+  *s = "not empty"E;
+  // expected-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and a macro}}
+#undef E
 #endif
 }
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -16571,8 +16571,7 @@
 //   contain a double underscore __ are reserved for use by C++
 //   implementations.
 Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved)
-<< static_cast(Status)
-<< StringLiteralParser::isValidUDSuffix(getLangOpts(), II->getName());
+<< static_cast(Status);
   }
 
   return false;
Index: clang/lib/Lex/Lexer.cpp
===
--- clang/lib/Lex/Lexer.cpp
+++ clang/lib/Lex/Lexer.cpp
@@ -1986,36 +1986,26 @@
   assert(LangOpts.CPlusPlus);
 
   // Maximally munch an identifier.
+  const char *const TokStart = CurPtr;
   unsigned Size;
   char C = getCharAndSize(CurPtr, Size);
-  bool Consumed = 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-20 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

D158372  addresses comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153156

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


[PATCH] D158372: [Clang] Treat invalid UDL as two tokens

2023-08-20 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: clang-language-wg, aaron.ballman, jyknight.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As a language extension, if an invalid a UDL's suffix can result in macro
expansion, it is treated as if whitespace preceded it. This allows legacy
code to co-exist with new code via -Wno-reserved-user-defined-literal.
The following code results in string concat not calling literal operator.

  const char* s = "FOO"BAR;

Address comments in D153156 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158372

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp

Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator ""wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
-void operator ""wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator ""wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved}}
 
 template
 void f() {
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -143,7 +143,7 @@
 #if __cplusplus >= 201103L
   float operator ""_E(const char *);
   float operator ""E(const char *);
-  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved}}
 #endif
 }
 
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -489,7 +489,13 @@
 #if __cplusplus >= 201103L
   float operator ""_E(const char *);
   float operator ""E(const char *); // don't err on the lack of spaces even when the literal suffix identifier is invalid
-  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+  // expected-warning@-1 {{user-defined literal suffixes not starting with '_' are reserved}}
+  const char* s0 = "FOO"BAR;
+  // expected-error@-1 {{no matching literal operator for call to 'operator""BAR' with arguments of types 'const char *' and 'unsigned long', and no matching literal operator template}}
+#define BAR "BAZ"
+  const char* s1 = "FOO"BAR;
+  // expected-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and a macro}}
+#undef BAR
 #endif
 }
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -16571,8 +16571,7 @@
 //   contain a double underscore __ are reserved for use by C++
 //   implementations.
 Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved)
-<< static_cast(Status)
-<< StringLiteralParser::isValidUDSuffix(getLangOpts(), II->getName());
+<< static_cast(Status);
   }
 
   return false;
Index: clang/lib/Lex/Lexer.cpp
===
--- clang/lib/Lex/Lexer.cpp
+++ clang/lib/Lex/Lexer.cpp
@@ -1986,6 +1986,7 @@
   assert(LangOpts.CPlusPlus);
 
   // Maximally munch an identifier.
+  const char *TokStart = CurPtr;
   unsigned Size;
   char C = getCharAndSize(CurPtr, Size);
   bool Consumed = false;
@@ -2012,10 +2013,43 @@
   // that does not start with an underscore is ill-formed. We assume a suffix
   // beginning with a UCN or UTF-8 character is more likely to be a ud-suffix
   // than a macro, however, and accept that.
+  bool IsUDSuffix = false;
+  if (!Consumed) {
+if (C == '_')
+  IsUDSuffix = true;
+else if (IsStringLiteral && LangOpts.CPlusPlus14) {
+  // In C++1y, we need to look ahead a few characters to see if this is a
+  // valid suffix for a string literal or a numeric literal (this could be
+  // the 'operator""if' defining a numeric 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-18 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

I’ll see what I can do regarding reviving the string concat behavior. It feels 
like that a more refined treatment than before can be achieved. Maybe adds an 
imaginary preceding whitespace only when we can find a macro with the same name.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153156

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


[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-18 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

In D153156#4599324 , @jyknight wrote:

> If proper spec-conformance means we can no longer support the ability to 
> allow such out-of-spec pre-c++11 code to work anymore, that's probably 
> OK...but, in that case, we also need to eliminate the warning option, and 
> mention the change in the release notes.

Works in C++98 mode tho. TIL people exploit this to mix pre-C++11 code into 
modern C++. I agree that a reminder for those people in the release note is 
needed.

> And, if that _was_ an intended change, then we have other diagnostics which 
> need to be fixed up now

Agreed

In D153156#4599292 , @rupprecht wrote:

> IIUC, the question is not whether the diagnostic is correct, but rather why 
> `-Wno-reserved-user-defined-literal` does not workaround the breakage. Is 
> that right?
>
> An example of this in the wild is older versions of swig: 
> https://github.com/swig/swig/blob/939dd5e1c8c17e5f8b38747bf18e9041ab5f377e/Source/Modules/php.cxx#L1724

We simply stop pretending a whitespace precedes an invalid ud-suffix as that 
affects the grammar production and therefore diagnosis in Sema.
IMHO, people should stop  using `-Wno-reserved-user-defined-literal` and 
exploiting the addition of a whitespace to mingle pre-c++11 and post-c++11 code.
What if a programmer is really trying to call operator""b here (albeit 
ill-formed):

  const char* operator""b(const char*, decltype(sizeof 0));
  const char* f() {
  #define b "a"
return "ONE"b; // NOW: IFNDR but calls operator""b
   //
   // BEFORE: string concat by exploiting the impl of
   // ext_reserved_user_defined_literal (controlled by
   // -Wreserved-user-defined-literal diag group)
  }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153156

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


[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-18 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

In D153156#4598915 , @steelannelida 
wrote:

> Unfortunately the option -Wno-reserved-user-defined-literal fails after this:
>
>   #define MYTHING "_something_"
>   
>   const char* f() {
> return "ONE"MYTHING"TWO";
>   }
>
>   $ clang -Wno-reserved-user-defined-literal repro.cxx
>   repro.cxx:4:15: error: no matching literal operator for call to 
> 'operator""MYTHING' with arguments of types 'const char *' and 'unsigned 
> long', and no matching literal operator template
>   4 |   return "ONE"MYTHING"TWO";
> |   ^
>   1 error generated.

This is conforming right? Correct me if I'm wrong. My reading of 
https://eel.is/c++draft/lex.pptoken#3.3 is that "ONE"MYTHING"TWO" is a single 
preprocessing-token during phase 3 (https://eel.is/c++draft/lex.phases#1.3). 
Can @aaron.ballman confirm this?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153156

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


[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-17 Thread PoYao Chang via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf2583f3acf59: [Clang] CWG1473: do not err on the lack of 
space after operator (authored by rZhBoYao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 18
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,6 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp
===
--- clang/test/SemaCXX/literal-operators.cpp
+++ clang/test/SemaCXX/literal-operators.cpp
@@ -3,46 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-08-17 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 551138.
rZhBoYao marked 2 inline comments as done.
rZhBoYao added a comment.

Thank Aaron and Vlad for reviewing this! Just updating the diff to reflect the 
final version.


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

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 18
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,6 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp
===
--- clang/test/SemaCXX/literal-operators.cpp
+++ clang/test/SemaCXX/literal-operators.cpp
@@ -3,46 +3,46 @@
 #include 
 
 struct tag {
-  void operator "" _tag_bad (const char *); 

[PATCH] D155081: Specify the developer policy around links to external resources

2023-08-11 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added inline comments.



Comment at: llvm/docs/DeveloperPolicy.rst:359
+  If the patch fixes a bug in GitHub Issues, we encourage adding
+  "Fixes https://github.com/llvm/llvm-project/issues/12345; to automate closing
+  the issue in GitHub. If the patch has been reviewed, we encourage adding a

probinson wrote:
> mehdi_amini wrote:
> > ldionne wrote:
> > > smeenai wrote:
> > > > aaron.ballman wrote:
> > > > > arsenm wrote:
> > > > > > I haven't quite figured out what the exact syntaxes which are 
> > > > > > automatically recognized. It seems to recognize "Fixes #Nxyz"
> > > > > Yup, it does support that form as well. I had heard more than once 
> > > > > during code review that folks seem to prefer the full link because 
> > > > > it's easier to click on that from the commit message than it is to 
> > > > > navigate to the fix from the number alone. That seemed like a pretty 
> > > > > good reason to recommend the full form, but I don't have strong 
> > > > > opinions.
> > > > +1 for encouraging the full link
> > > Perhaps we could encourage using `https://llvm.org/PR12345` instead? Does 
> > > anybody know whether `llvm.org/PRXXX` is something that we intend to keep 
> > > around with the Github transition or not?
> > @arsenm: It's documented 
> > https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword
> > And for linking cross-repo: 
> > https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls#issues-and-pull-requests
> > Perhaps we could encourage using `https://llvm.org/PR12345` instead? Does 
> > anybody know whether `llvm.org/PRXXX` is something that we intend to keep 
> > around with the Github transition or not?
> 
> Currently the PRxxx links are to the old bugzillas, not the Github issues. It 
> might be sad to lose that.
If the full link is preferred, can you update the first bullet point in [[ 
https://llvm.org/docs/BugLifeCycle.html#resolving-closing-bugs | the 
Resolving/Closing bugs section of LLVM Bug Life Cycle ]]?


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

https://reviews.llvm.org/D155081

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


[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Thanks for all the suggestions and review comments!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156063

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


[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbed75faf7d76: [Clang] Reject programs declaring namespace 
std to be inline (authored by rZhBoYao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156063

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===
--- clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 
 // FIXME: We should probably suppress the warning on reopening an inline
 // namespace without the inline keyword if it's not the first opening of the
@@ -16,3 +16,11 @@
   inline namespace {} // expected-note {{previous definition}}
   namespace {} // expected-warning {{inline namespace reopened as a non-inline 
namespace}}
 }
+
+namespace std {}
+inline namespace std {} // expected-error{{cannot declare the namespace 'std' 
to be inline}}
+inline namespace std::foo {} // expected-error{{cannot declare the namespace 
'std' to be inline}}
+ // expected-error@-1{{nested namespace definition 
cannot be 'inline'}}
+namespace foo::inline std {} // expected-note {{previous definition}}
+namespace foo { inline namespace std {} } // OK
+namespace foo { namespace std {} } // expected-warning {{inline namespace 
reopened as a non-inline namespace}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11388,6 +11388,20 @@
 
   NamespaceDecl *PrevNS = nullptr;
   if (II) {
+// C++ [namespace.std]p7:
+//   A translation unit shall not declare namespace std to be an inline
+//   namespace (9.8.2).
+//
+// Precondition: the std namespace is in the file scope and is declared to
+// be inline
+auto DiagnoseInlineStdNS = [&]() {
+  assert(IsInline && II->isStr("std") &&
+ CurContext->getRedeclContext()->isTranslationUnit() &&
+ "Precondition of DiagnoseInlineStdNS not met");
+  Diag(InlineLoc, diag::err_inline_namespace_std)
+  << SourceRange(InlineLoc, InlineLoc.getLocWithOffset(6));
+  IsInline = false;
+};
 // C++ [namespace.def]p2:
 //   The identifier in an original-namespace-definition shall not
 //   have been previously defined in the declarative region in
@@ -11408,7 +11422,10 @@
 
 if (PrevNS) {
   // This is an extended namespace definition.
-  if (IsInline != PrevNS->isInline())
+  if (IsInline && II->isStr("std") &&
+  CurContext->getRedeclContext()->isTranslationUnit())
+DiagnoseInlineStdNS();
+  else if (IsInline != PrevNS->isInline())
 DiagnoseNamespaceInlineMismatch(*this, NamespaceLoc, Loc, II,
 , PrevNS);
 } else if (PrevDecl) {
@@ -11420,6 +11437,8 @@
   // Continue on to push Namespc as current DeclContext and return it.
 } else if (II->isStr("std") &&
CurContext->getRedeclContext()->isTranslationUnit()) {
+  if (IsInline)
+DiagnoseInlineStdNS();
   // This is the first "real" definition of the namespace "std", so update
   // our cache of the "std" namespace to point at this definition.
   PrevNS = getStdNamespace();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,8 @@
   InGroup;
 def err_inline_namespace_mismatch : Error<
   "non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+  "cannot declare the namespace 'std' to be inline">;
 
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -84,6 +84,7 @@
   directly rather than instantiating the definition from the standard library.
 - Implemented `CWG2518 `_ which allows 
``static_assert(false)``
   to not be ill-formed when its condition is evaluated in the context of a 
template definition.
+- Declaring namespace std to be an inline namespace is now prohibited, 
`[namespace.std]p7`.
 
 C++20 Feature Support
 ^


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp

[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 543559.
rZhBoYao added a comment.

Refactor VisitCXXOperatorCallExpr and mark CWG2571 as done in Clang 15 
(deliberately the same version P2128R6 was implemented) since this patch only 
fix the diagnostics around it.


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

https://reviews.llvm.org/D156057

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/SemaCXX/warn-unsequenced.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
@@ -15233,7 +15233,7 @@
 https://cplusplus.github.io/CWG/issues/2571.html;>2571
 CD6
 Evaluation order for subscripting
-Unknown
+Clang 15
   
   
 https://cplusplus.github.io/CWG/issues/2572.html;>2572
Index: clang/test/SemaCXX/warn-unsequenced.cpp
===
--- clang/test/SemaCXX/warn-unsequenced.cpp
+++ clang/test/SemaCXX/warn-unsequenced.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN:-Wunsequenced -Windeterminately-sequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify=since-cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced -Windeterminately-sequenced %s
+// RUN: %clang_cc1 -fsyntax-only -verify=since-cxx17 -std=c++23 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced -Windeterminately-sequenced %s
 
 int f(int, int = 0);
 int g1();
@@ -20,17 +22,17 @@
   int xs[10];
   ++a = 0; // ok
   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
   a = ++a; // ok
   a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
   a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   ++ ++a; // ok
   (a++, a++); // ok
   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ // since-cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
   a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ // since-cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
   (a++, a) = 0; // ok, increment is sequenced before value computation of LHS
   a = xs[++a]; // ok
   a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
@@ -40,15 +42,15 @@
   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   f(a, a); // ok
   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
-// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+// since-cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // since-cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
   a = f(++a); // ok
   a = f(a++); // ok
   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // since-cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
 
   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
   // is evaluated only once.
@@ -59,73 +61,73 @@
 
   A agg1 = { a++, a++ }; // ok
   A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
- // cxx17-warning@-1 {{unsequenced modification and access to 

[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Thanks for the reminder. I am aware of that. Browsing through 762672a73a1e 
 and a560ccf2af7a 
, I believe the 
indeterminately sequenced requirement is met, neither of which test the codegen 
so I might just put the example shown in the release note in dr25xx.cpp.

In D156057#4527821 , @Endill wrote:

> In D156057#4527787 , @rZhBoYao 
> wrote:
>
>> BTW, I am not sure if CWG2571  is implemented by 
>> @cor3ntin? If so, can we mark it as done on 
>> https://clang.llvm.org/cxx_dr_status.html#2571? This patch handles the 
>> warning around it tho.
>
> As a reminder, we don't change `cxx_dr_status.html` directly. Instead, we add 
> a special comment in `clang/test/CXX/drs/dr25xx.cpp` (for the case of 
> CWG2571), which should be accompanied by test case(s) if possible. You can 
> follow the pattern of existing tests. After that 
> `clang/www/make_cxx_dr_status` script should be run to update the HTML.




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

https://reviews.llvm.org/D156057

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


[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 543514.
rZhBoYao marked an inline comment as done.
rZhBoYao added a comment.

Addressed comments


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

https://reviews.llvm.org/D156063

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===
--- clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 
 // FIXME: We should probably suppress the warning on reopening an inline
 // namespace without the inline keyword if it's not the first opening of the
@@ -16,3 +16,11 @@
   inline namespace {} // expected-note {{previous definition}}
   namespace {} // expected-warning {{inline namespace reopened as a non-inline 
namespace}}
 }
+
+namespace std {}
+inline namespace std {} // expected-error{{cannot declare the namespace 'std' 
to be inline}}
+inline namespace std::foo {} // expected-error{{cannot declare the namespace 
'std' to be inline}}
+ // expected-error@-1{{nested namespace definition 
cannot be 'inline'}}
+namespace foo::inline std {} // expected-note {{previous definition}}
+namespace foo { inline namespace std {} } // OK
+namespace foo { namespace std {} } // expected-warning {{inline namespace 
reopened as a non-inline namespace}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11361,6 +11361,20 @@
 
   NamespaceDecl *PrevNS = nullptr;
   if (II) {
+// C++ [namespace.std]p7:
+//   A translation unit shall not declare namespace std to be an inline
+//   namespace (9.8.2).
+//
+// Precondition: the std namespace is in the file scope and is declared to
+// be inline
+auto DiagnoseInlineStdNS = [&]() {
+  assert(IsInline && II->isStr("std") &&
+ CurContext->getRedeclContext()->isTranslationUnit() &&
+ "Precondition of DiagnoseInlineStdNS not met");
+  Diag(InlineLoc, diag::err_inline_namespace_std)
+  << SourceRange(InlineLoc, InlineLoc.getLocWithOffset(6));
+  IsInline = false;
+};
 // C++ [namespace.def]p2:
 //   The identifier in an original-namespace-definition shall not
 //   have been previously defined in the declarative region in
@@ -11381,7 +11395,10 @@
 
 if (PrevNS) {
   // This is an extended namespace definition.
-  if (IsInline != PrevNS->isInline())
+  if (IsInline && II->isStr("std") &&
+  CurContext->getRedeclContext()->isTranslationUnit())
+DiagnoseInlineStdNS();
+  else if (IsInline != PrevNS->isInline())
 DiagnoseNamespaceInlineMismatch(*this, NamespaceLoc, Loc, II,
 , PrevNS);
 } else if (PrevDecl) {
@@ -11393,6 +11410,8 @@
   // Continue on to push Namespc as current DeclContext and return it.
 } else if (II->isStr("std") &&
CurContext->getRedeclContext()->isTranslationUnit()) {
+  if (IsInline)
+DiagnoseInlineStdNS();
   // This is the first "real" definition of the namespace "std", so update
   // our cache of the "std" namespace to point at this definition.
   PrevNS = getStdNamespace();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,8 @@
   InGroup;
 def err_inline_namespace_mismatch : Error<
   "non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+  "cannot declare the namespace 'std' to be inline">;
 
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -84,6 +84,7 @@
   directly rather than instantiating the definition from the standard library.
 - Implemented `CWG2518 `_ which allows 
``static_assert(false)``
   to not be ill-formed when its condition is evaluated in the context of a 
template definition.
+- Declaring namespace std to be an inline namespace is now prohibited, 
`[namespace.std]p7`.
 
 C++20 Feature Support
 ^


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===
--- 

[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-24 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a subscriber: cor3ntin.
rZhBoYao added a comment.

BTW, I am not sure if CWG2571  is implemented by 
@cor3ntin? If so, can we mark it as done on 
https://clang.llvm.org/cxx_dr_status.html#2571? This patch handles the warning 
around it tho.


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

https://reviews.llvm.org/D156057

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


[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 543315.
rZhBoYao marked an inline comment as done.
rZhBoYao added a comment.

Improve the test.

Not sure what the lack of C++17 checks was referring to in your conversation 
with Aaron.
Can @aaron.ballman confirm whether it is addressed by this patch?


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

https://reviews.llvm.org/D156057

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/warn-unsequenced.cpp

Index: clang/test/SemaCXX/warn-unsequenced.cpp
===
--- clang/test/SemaCXX/warn-unsequenced.cpp
+++ clang/test/SemaCXX/warn-unsequenced.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN:-Wunsequenced -Windeterminately-sequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify=since-cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced -Windeterminately-sequenced %s
+// RUN: %clang_cc1 -fsyntax-only -verify=since-cxx17 -std=c++23 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced -Windeterminately-sequenced %s
 
 int f(int, int = 0);
 int g1();
@@ -20,17 +22,17 @@
   int xs[10];
   ++a = 0; // ok
   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
   a = ++a; // ok
   a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
   a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   ++ ++a; // ok
   (a++, a++); // ok
   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ // since-cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
   a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ // since-cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
   (a++, a) = 0; // ok, increment is sequenced before value computation of LHS
   a = xs[++a]; // ok
   a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
@@ -40,15 +42,15 @@
   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   f(a, a); // ok
   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // since-cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
-// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+// since-cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // since-cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
   a = f(++a); // ok
   a = f(a++); // ok
   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // since-cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
 
   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
   // is evaluated only once.
@@ -59,73 +61,73 @@
 
   A agg1 = { a++, a++ }; // ok
   A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
- // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+ // since-cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
 
   S str1(a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-// cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+// since-cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
   S str2 = { a++, a++ }; // ok
   S str3 = { a++ + 

[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline

2023-07-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

https://eel.is/c++draft/namespace.std#7 is in the library clause.
Couldn't find a better place to put the test other than 
clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp which is for 
https://eel.is/c++draft/namespace.def.general#4.sentence-2.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156063

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


[PATCH] D156063: [Clang] Reject programs declaring namespace std to be inline

2023-07-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: philnik, clang-language-wg.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156063

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===
--- clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -16,3 +16,6 @@
   inline namespace {} // expected-note {{previous definition}}
   namespace {} // expected-warning {{inline namespace reopened as a non-inline 
namespace}}
 }
+
+inline namespace std {}
+// expected-error@-1{{namespace 'std' cannot be declared to be inline}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11361,6 +11361,14 @@
 
   NamespaceDecl *PrevNS = nullptr;
   if (II) {
+// C++ [namespace.std]p7:
+//   A translation unit shall not declare namespace std to be an inline
+//   namespace (9.8.2).
+//
+// This has to be diagnosed before entering 
DiagnoseNamespaceInlineMismatch.
+if (IsInline && II->isStr("std"))
+  Diag(InlineLoc, diag::err_inline_namespace_std)
+  << SourceRange(InlineLoc, InlineLoc.getLocWithOffset(6));
 // C++ [namespace.def]p2:
 //   The identifier in an original-namespace-definition shall not
 //   have been previously defined in the declarative region in
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,8 @@
   InGroup;
 def err_inline_namespace_mismatch : Error<
   "non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+  "namespace 'std' cannot be declared to be inline">;
 
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -84,6 +84,7 @@
   directly rather than instantiating the definition from the standard library.
 - Implemented `CWG2518 `_ which allows 
``static_assert(false)``
   to not be ill-formed when its condition is evaluated in the context of a 
template definition.
+- Declaring namespace std to be an inline namespace is now prohibited, 
`[namespace.std]p7`.
 
 C++20 Feature Support
 ^


Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
===
--- clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
+++ clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -16,3 +16,6 @@
   inline namespace {} // expected-note {{previous definition}}
   namespace {} // expected-warning {{inline namespace reopened as a non-inline namespace}}
 }
+
+inline namespace std {}
+// expected-error@-1{{namespace 'std' cannot be declared to be inline}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -11361,6 +11361,14 @@
 
   NamespaceDecl *PrevNS = nullptr;
   if (II) {
+// C++ [namespace.std]p7:
+//   A translation unit shall not declare namespace std to be an inline
+//   namespace (9.8.2).
+//
+// This has to be diagnosed before entering DiagnoseNamespaceInlineMismatch.
+if (IsInline && II->isStr("std"))
+  Diag(InlineLoc, diag::err_inline_namespace_std)
+  << SourceRange(InlineLoc, InlineLoc.getLocWithOffset(6));
 // C++ [namespace.def]p2:
 //   The identifier in an original-namespace-definition shall not
 //   have been previously defined in the declarative region in
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1579,6 +1579,8 @@
   InGroup;
 def err_inline_namespace_mismatch : Error<
   "non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+  "namespace 'std' cannot be declared to be inline">;
 
 def err_unexpected_friend : Error<
   "friends can only be classes or functions">;
Index: clang/docs/ReleaseNotes.rst
===
--- 

[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 543295.
rZhBoYao added a comment.

Put `-Windeterminately-sequenced` under `-Wsequence-point`'s control


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

https://reviews.llvm.org/D156057

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/warn-unsequenced.cpp

Index: clang/test/SemaCXX/warn-unsequenced.cpp
===
--- clang/test/SemaCXX/warn-unsequenced.cpp
+++ clang/test/SemaCXX/warn-unsequenced.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
 // RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++23 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced %s
 
 int f(int, int = 0);
 int g1();
@@ -40,15 +40,15 @@
   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   f(a, a); // ok
   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
-// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+// cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
   a = f(++a); // ok
   a = f(a++); // ok
   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
 
   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
   // is evaluated only once.
@@ -279,15 +279,18 @@
   // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
 
   (i++, f)(i++, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
+  f((++i, f)(i++, j++), ++j); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
+  // cxx11-warning@-1 {{multiple unsequenced modifications to 'j'}}
+  // cxx17-warning@-2 {{multiple indeterminately sequenced modifications to 'j'}}
   (i++ + i++, f)(42, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
   // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
   int (*pf)(int, int);
   (pf = f)(pf != nullptr, pf != nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
   pf((pf = f) != nullptr, 42); // cxx11-warning {{unsequenced modification and access to 'pf'}}
   f((pf = f, 42), (pf = f, 42)); // cxx11-warning {{multiple unsequenced modifications to 'pf'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'pf'}}
+ // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'pf'}}
   pf((pf = f) != nullptr, pf == nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
-  // cxx17-warning@-1 {{unsequenced modification and access to 'pf'}}
+  // cxx17-warning@-1 {{indeterminately sequenced modification and access to 'pf'}}
 }
 
 namespace PR20819 {
@@ -305,7 +308,11 @@
 E =(E &);
 E operator()(E);
 E operator()(E, E);
+#if __cplusplus >= 202302L
+E operator[](auto...);
+#else
 E operator[](E);
+#endif
   } e;
   // Binary operators with unsequenced operands.
   E operator+(E,E);
@@ -417,7 +424,7 @@
 
 operator+=(((void)i++,e), ((void)i++,e));
 // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
-// cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
+// cxx17-warning@-2 {{multiple indeterminately sequenced modifications to 'i'}}
 
 // Binary operators where the LHS is sequenced before the RHS in C++17.
 ((void)i++,e) << ((void)i++,e);
@@ -435,16 +442,21 @@
 
 operator<<(((void)i++,e), ((void)i++,e));
 // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
-// cxx17-warning@-2 {{multiple unsequenced 

[PATCH] D156057: [Clang][Sema] Diagnose indeterminately sequenced accesses

2023-07-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: aaron.ballman, Endill, clang-language-wg.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Add -Windeterminately-sequenced and fix -Wunsequenced according to P0400R0 and 
CWG2571.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156057

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/warn-unsequenced.cpp

Index: clang/test/SemaCXX/warn-unsequenced.cpp
===
--- clang/test/SemaCXX/warn-unsequenced.cpp
+++ clang/test/SemaCXX/warn-unsequenced.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
 // RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
-// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
-// RUN:-Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++23 -Wno-unused -Wno-uninitialized \
+// RUN:-Wunsequenced %s
 
 int f(int, int = 0);
 int g1();
@@ -40,15 +40,15 @@
   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
   f(a, a); // ok
   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
-   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+   // cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
-// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+// cxx17-warning@-1 {{indeterminately sequenced modification and access to 'a'}}
   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
   a = f(++a); // ok
   a = f(a++); // ok
   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
-   // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+   // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'a'}}
 
   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
   // is evaluated only once.
@@ -279,15 +279,18 @@
   // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
 
   (i++, f)(i++, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
+  f((++i, f)(i++, j++), ++j); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
+  // cxx11-warning@-1 {{multiple unsequenced modifications to 'j'}}
+  // cxx17-warning@-2 {{multiple indeterminately sequenced modifications to 'j'}}
   (i++ + i++, f)(42, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
   // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
   int (*pf)(int, int);
   (pf = f)(pf != nullptr, pf != nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
   pf((pf = f) != nullptr, 42); // cxx11-warning {{unsequenced modification and access to 'pf'}}
   f((pf = f, 42), (pf = f, 42)); // cxx11-warning {{multiple unsequenced modifications to 'pf'}}
- // cxx17-warning@-1 {{multiple unsequenced modifications to 'pf'}}
+ // cxx17-warning@-1 {{multiple indeterminately sequenced modifications to 'pf'}}
   pf((pf = f) != nullptr, pf == nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
-  // cxx17-warning@-1 {{unsequenced modification and access to 'pf'}}
+  // cxx17-warning@-1 {{indeterminately sequenced modification and access to 'pf'}}
 }
 
 namespace PR20819 {
@@ -305,7 +308,11 @@
 E =(E &);
 E operator()(E);
 E operator()(E, E);
+#if __cplusplus >= 202302L
+E operator[](auto...);
+#else
 E operator[](E);
+#endif
   } e;
   // Binary operators with unsequenced operands.
   E operator+(E,E);
@@ -417,7 +424,7 @@
 
 operator+=(((void)i++,e), ((void)i++,e));
 // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
-// cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
+// cxx17-warning@-2 {{multiple indeterminately sequenced modifications to 'i'}}
 
 // Binary operators where the LHS is sequenced before the RHS in C++17.
 ((void)i++,e) << ((void)i++,e);
@@ -435,16 +442,21 @@
 
 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-07-20 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Gentle ping :)


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

https://reviews.llvm.org/D153156

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


[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-07-18 Thread PoYao Chang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5ce5e983f82c: [Clang] Add warnings for CWG2521 (authored by 
rZhBoYao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr25xx.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/CXX/drs/dr25xx.cpp
===
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,14 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
 
 namespace dr2516 { // dr2516: yes
// NB: reusing 1482 test
@@ -13,9 +23,13 @@
 
 namespace dr2518 { // dr2518: 17
 
+#if __cplusplus >= 201103L
 template 
 void f(T t) {
   if constexpr (sizeof(T) != sizeof(int)) {
+#if __cplusplus < 201703L
+// expected-error@-2 {{constexpr if is a C++17 extension}}
+#endif
 static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
   }
 }
@@ -28,6 +42,9 @@
 template 
 struct S {
   static_assert(false); // expected-error {{static assertion failed}}
+#if __cplusplus < 201703L
+// expected-error@-2 {{'static_assert' with no message is a C++17 extension}}
+#endif
 };
 
 template <>
@@ -41,11 +58,31 @@
   S s2;
   S s3; // expected-note {{in instantiation of template class 'dr2518::S' requested here}}
 }
+#endif
 
 }
 
+namespace dr2521 { // dr2521: 17
+#if __cplusplus >= 201103L
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wdeprecated-literal-operator"
+long double operator""  _\u03C0___(long double);
+// expected-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+// expected-warning@-2 {{user-defined literal suffixes containing '__' are reserved}}
+
+template  decltype(sizeof 0)
+operator""  _div();
+// expected-warning@-1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}}
+
+using ::dr2521::operator"" _\u03C0___;
+using ::dr2521::operator""_div;
+// expected-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+#pragma clang diagnostic pop
+#endif
+} // namespace dr2521
 
 namespace dr2565 { // dr2565: 16 open
+#if __cplusplus >= 202002L
   template
 concept C = requires (typename T::type x) {
   x + 1;
@@ -107,4 +144,5 @@
   // expected-error@-1{{static assertion failed}}
   // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
+#endif
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -502,13 +502,16 @@
 IdentifierInfo *II = Name.Identifier;
 ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
 SourceLocation Loc = Name.getEndLoc();
-if (isReservedInAllContexts(Status) &&
-!PP.getSourceManager().isInSystemHeader(Loc)) {
-  Diag(Loc, diag::warn_reserved_extern_symbol)
-  << II << static_cast(Status)
-  << FixItHint::CreateReplacement(
- Name.getSourceRange(),
- (StringRef("operator\"\"") + II->getName()).str());
+if 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-07-17 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

There seems to be no clear objection to this and 
https://reviews.llvm.org/D152632 and the CI are passing for both.  Any chance 
that I merge these two before llvm 17 branch out (IIRC the next Monday)?


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

https://reviews.llvm.org/D153156

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


[PATCH] D155475: [Clang][Sema] Add -Wctad-selects-copy to diagnose copy deduction candidate

2023-07-17 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 541151.
rZhBoYao retitled this revision from "[Clang][Sema] Add -Wctad-copy-not-wrap to 
diagnose copy deduction candidate" to "[Clang][Sema] Add -Wctad-selects-copy to 
diagnose copy deduction candidate".
rZhBoYao edited the summary of this revision.

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

https://reviews.llvm.org/D155475

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaTemplate/ctad.cpp

Index: clang/test/SemaTemplate/ctad.cpp
===
--- clang/test/SemaTemplate/ctad.cpp
+++ clang/test/SemaTemplate/ctad.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++23 -verify %s
 
 namespace pr41427 {
   template  class A {
@@ -44,3 +44,32 @@
   };
   D z = {Z(), {}};
 }
+
+namespace warn_ctad_copy {
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wctad-selects-copy"
+// like std::revrse_iterator, the motivating example
+template  struct CTAD {
+  template 
+requires(!__is_same(From, T) && __is_convertible_to(From, T))
+  CTAD(const CTAD&) {} // #1
+  CTAD(T) {}
+};
+CTAD(void) -> CTAD; // does not suppress -Wctad-selects-copy
+
+CTAD&   fc1();
+CTAD fc2(),
+ c1 = fc1(); // uses #1
+CTAD c2 = fc2(), // OK, uses copy-initialization
+ c3 = CTAD(4.2); // OK, copy deduction candidate not selected
+CTAD c4{fc2()};  // test prvalue expression
+// expected-warning@-1{{move-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-list-initialization to suppress this warning}}
+CTAD c5 = CTAD{fc1()};   // test lvalue  expression
+// expected-warning@-1{{copy-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-list-initialization to suppress this warning}}
+auto c6 = CTAD((CTAD&&)c5); // test xvalue  expression
+// expected-warning@-1{{move-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-initialization to suppress this warning}}
+#pragma clang diagnostic pop
+} // namespace warn_ctad_copy
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -19,6 +19,7 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
@@ -10908,6 +10909,18 @@
diag::warn_cxx14_compat_class_template_argument_deduction)
   << TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType;
 
+  // Warn if the copy deduction candidate is selected in direct-initialization.
+  auto DiagnoseCTADCopy = [&] {
+if (auto IK = Kind.getKind();
+IK <= InitializationKind::IK_DirectList &&
+cast(Best->Function)
+->getDeductionCandidateKind() == DeductionCandidate::Copy) {
+  Diag(Kind.getLocation(), diag::warn_ctad_selects_copy)
+  << Kind.getRange() << Inits.front()->isLValue() << DeducedType
+  << !ListInit;
+}
+  };
+
   // Warn if CTAD was used on a type that does not have any user-defined
   // deduction guides.
   if (!FoundDeductionGuide) {
@@ -10915,6 +10928,9 @@
  diag::warn_ctad_maybe_unsupported)
 << TemplateName;
 Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported);
+DiagnoseCTADCopy();
+  } else if (!PP.getSourceManager().isInSystemHeader(Template->getLocation())) {
+DiagnoseCTADCopy();
   }
 
   return DeducedType;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2488,6 +2488,10 @@
   InGroup, DefaultIgnore;
 def note_suppress_ctad_maybe_unsupported : Note<
   "add a deduction guide to suppress this warning">;
+def warn_ctad_selects_copy : Warning<
+  "%select{move|copy}0-constructing not wrapping a %1, "
+  "use copy-%select{list-|}2initialization to suppress this warning">,
+  InGroup, DefaultIgnore;
 
 
 // C++14 deduced return types
Index: clang/include/clang/Basic/DiagnosticGroups.td
===
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1380,6 +1380,10 @@
 def CrossTU : DiagGroup<"ctu">;
 
 def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">;
+def CTADSelectsCopy  : DiagGroup<"ctad-selects-copy">;
+def CTADMaybeUnintended  : DiagGroup<"ctad-maybe-unintended", [
+CTADMaybeUnsupported, CTADSelectsCopy
+  ]>;
 
 def 

[PATCH] D155475: [Clang][Sema] Add -Wctad-copy-not-wrap to diagnose copy deduction candidate

2023-07-17 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: EricWF, rsmith.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

1. '-Wctad-copy-not-wrap' warns when copy deduction candidate is selected in 
CTAD, and the initialization is a direct-initialization. The warning is 
suppressed when the class template is in a system header and has at least one 
explicit deduction guide.
2. Add a group '-Wctad' which incldues '-Wctad-copy-not-wrap' and 
'-Wctad-maybe-unsupported'.

Fixes #63288


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155475

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaTemplate/ctad.cpp

Index: clang/test/SemaTemplate/ctad.cpp
===
--- clang/test/SemaTemplate/ctad.cpp
+++ clang/test/SemaTemplate/ctad.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++23 -verify %s
 
 namespace pr41427 {
   template  class A {
@@ -44,3 +44,32 @@
   };
   D z = {Z(), {}};
 }
+
+namespace warn_ctad_copy {
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wctad-copy-not-wrap"
+// like std::revrse_iterator, the motivating example
+template  struct CTAD {
+  template 
+requires(!__is_same(From, T) && __is_convertible_to(From, T))
+  CTAD(const CTAD&) {} // #1
+  CTAD(T) {}
+};
+CTAD(void) -> CTAD; // does not suppress -Wctad-copy-not-wrap
+
+CTAD&   fc1();
+CTAD fc2(),
+ c1 = fc1(); // uses #1
+CTAD c2 = fc2(), // OK, uses copy-initialization
+ c3 = CTAD(4.2), // OK, copy deduction candidate not selected
+ c4{fc2()};  // test prvalue expression
+// expected-warning@-1{{move-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-list-initialization to suppress this warning}}
+CTAD c5 = CTAD{fc1()},   // test lvalue  expression
+// expected-warning@-1{{copy-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-list-initialization to suppress this warning}}
+ c6 = CTAD((CTAD&&)c5); // test xvalue  expression
+// expected-warning@-1{{move-constructing not wrapping a 'CTAD' \
+(aka 'warn_ctad_copy::CTAD'), use copy-initialization to suppress this warning}}
+#pragma clang diagnostic pop
+} // namespace warn_ctad_copy
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -19,6 +19,7 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/EnterExpressionEvaluationContext.h"
 #include "clang/Sema/Initialization.h"
@@ -10908,6 +10909,17 @@
diag::warn_cxx14_compat_class_template_argument_deduction)
   << TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType;
 
+  // Warn if the copy deduction candidate is selected in direct-initialization.
+  auto DiagnoseCTADCopy = [&] {
+if (auto IK = Kind.getKind();
+IK <= InitializationKind::IK_DirectList &&
+cast(Best->Function)
+->getDeductionCandidateKind() == DeductionCandidate::Copy) {
+  Diag(Kind.getLocation(), diag::warn_ctad_copy_not_wrap)
+  << Inits.front()->isLValue() << DeducedType << !ListInit;
+}
+  };
+
   // Warn if CTAD was used on a type that does not have any user-defined
   // deduction guides.
   if (!FoundDeductionGuide) {
@@ -10915,6 +10927,9 @@
  diag::warn_ctad_maybe_unsupported)
 << TemplateName;
 Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported);
+DiagnoseCTADCopy();
+  } else if (!PP.getSourceManager().isInSystemHeader(Template->getLocation())) {
+DiagnoseCTADCopy();
   }
 
   return DeducedType;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2488,6 +2488,10 @@
   InGroup, DefaultIgnore;
 def note_suppress_ctad_maybe_unsupported : Note<
   "add a deduction guide to suppress this warning">;
+def warn_ctad_copy_not_wrap : Warning<
+  "%select{move|copy}0-constructing not wrapping a %1, "
+  "use copy-%select{list-|}2initialization to suppress this warning">,
+  InGroup, DefaultIgnore;
 
 
 // C++14 deduced return types
Index: clang/include/clang/Basic/DiagnosticGroups.td
===
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1380,6 +1380,9 @@
 def CrossTU : DiagGroup<"ctu">;
 
 def 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-07-14 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Hmm… I don’t see why check-format keeps failing. I `git clang-format` thrice 
before uploading. 
https://buildkite.com/llvm-project/premerge-checks/builds/164452


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

https://reviews.llvm.org/D152632

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


[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-07-13 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 540104.
rZhBoYao marked an inline comment as done.
rZhBoYao edited the summary of this revision.

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

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,7 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
+void operator""_lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp
===
--- clang/test/SemaCXX/literal-operators.cpp
+++ clang/test/SemaCXX/literal-operators.cpp
@@ -3,46 +3,46 @@
 #include 
 
 struct tag {
-  void operator "" _tag_bad (const char *); // 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-07-13 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 540072.
rZhBoYao marked 6 inline comments as done.
rZhBoYao edited the summary of this revision.
rZhBoYao added a comment.

-Wdeprecated-literal-operator will be on by default in 
https://reviews.llvm.org/D153156


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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr25xx.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/CXX/drs/dr25xx.cpp
===
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,14 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
 
 namespace dr2516 { // dr2516: yes
// NB: reusing 1482 test
@@ -13,9 +23,13 @@
 
 namespace dr2518 { // dr2518: 17
 
+#if __cplusplus >= 201103L
 template 
 void f(T t) {
   if constexpr (sizeof(T) != sizeof(int)) {
+#if __cplusplus < 201703L
+// expected-error@-2 {{constexpr if is a C++17 extension}}
+#endif
 static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
   }
 }
@@ -28,6 +42,9 @@
 template 
 struct S {
   static_assert(false); // expected-error {{static assertion failed}}
+#if __cplusplus < 201703L
+// expected-error@-2 {{'static_assert' with no message is a C++17 extension}}
+#endif
 };
 
 template <>
@@ -41,11 +58,31 @@
   S s2;
   S s3; // expected-note {{in instantiation of template class 'dr2518::S' requested here}}
 }
+#endif
 
 }
 
+namespace dr2521 { // dr2521: 17
+#if __cplusplus >= 201103L
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wdeprecated-literal-operator"
+long double operator""  _\u03C0___(long double);
+// expected-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+// expected-warning@-2 {{user-defined literal suffixes containing '__' are reserved}}
+
+template  decltype(sizeof 0)
+operator""  _div();
+// expected-warning@-1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}}
+
+using ::dr2521::operator"" _\u03C0___;
+using ::dr2521::operator""_div;
+// expected-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+#pragma clang diagnostic pop
+#endif
+} // namespace dr2521
 
 namespace dr2565 { // dr2565: 16 open
+#if __cplusplus >= 202002L
   template
 concept C = requires (typename T::type x) {
   x + 1;
@@ -107,4 +144,5 @@
   // expected-error@-1{{static assertion failed}}
   // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
+#endif
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -502,13 +502,16 @@
 IdentifierInfo *II = Name.Identifier;
 ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
 SourceLocation Loc = Name.getEndLoc();
-if (isReservedInAllContexts(Status) &&
-!PP.getSourceManager().isInSystemHeader(Loc)) {
-  Diag(Loc, diag::warn_reserved_extern_symbol)
-  << II << static_cast(Status)
-  << FixItHint::CreateReplacement(
- Name.getSourceRange(),
- (StringRef("operator\"\"") + 

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-07-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 538707.

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

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,7 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
+void operator""_lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp
===
--- clang/test/SemaCXX/literal-operators.cpp
+++ clang/test/SemaCXX/literal-operators.cpp
@@ -3,46 +3,46 @@
 #include 
 
 struct tag {
-  void operator "" _tag_bad (const char *); // expected-error {{literal operator 'operator""_tag_bad' must be in a namespace or global scope}}
-  friend void operator 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-07-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 6 inline comments as done.
rZhBoYao added a comment.

In D152632#4443284 , @shafik wrote:

> I am wondering why we don't fold this into `-Wreserved-identifier`

The "ud-suffix" of the user-defined-string-literal or the identifier in a 
literal-operator-id is called a literal suffix identifier.
However "//ud-suffix//" and "identifiers appearing as a //token// or 
//preprocessing-token//" are treated differently in the standard.
Thus, I don't think folding -Wuser-defined-literals into -Wreserved-identifier 
is a good idea.




Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:411
+  "identifier '%0' preceded by space(s) in the literal operator declaration "
+  "is deprecated">, InGroup, DefaultIgnore;
 def warn_reserved_module_name : Warning<

rZhBoYao wrote:
> aaron.ballman wrote:
> > Oye, I'm of two minds about `DefaultIgnore`.
> > 
> > On the one hand, this is going to fire *a lot*: 
> > https://sourcegraph.com/search?q=context:global+operator%5B%5B:space:%5D%5D*%5C%22%5C%22%5B%5B:space:%5D%5D%5BA-Za-z0-9_%5D%2B=regexp=yes=1=repo
> > 
> > On the other hand, if we don't warn about it being deprecated, users won't 
> > know about it, which makes it harder to do anything about it the longer we 
> > silently allow it. (We have plenty of experience with this particular 
> > flavor of pain.)
> > 
> > I think we should warn about this by default. It's under its own warning 
> > group, so users who want to ignore the warning and live dangerously can do 
> > so. And it will be silenced in system headers automatically, so issuing the 
> > diagnostic should generally be actionable for users.
> I'm thinking the same after seeing [[ 
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2863r0.html#D.9 | 
> P2863R0 § 6.9 ]]
> 
> However, a lot of tests are written in the deprecated way. I think a patch 
> removing all the whitespaces only preceding this one is needed, to not 
> clutter up this one.
Default on and diagnose for C++23 only. Enable for all the lang modes in 
https://reviews.llvm.org/D153156



Comment at: clang/include/clang/Basic/IdentifierTable.h:56
+  NotStartsWithUnderscore,
+  ContainsDoubleUnderscore,
+};

shafik wrote:
> I would think starting with a double underscore would also not be allowed, at 
> least that is my reading.
That is indeed the case.


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

https://reviews.llvm.org/D152632

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


[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-07-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 538688.
rZhBoYao edited the summary of this revision.
rZhBoYao added a comment.

Reverse the dependency chain.


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

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,7 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
+void operator""_lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp
===
--- clang/test/SemaCXX/literal-operators.cpp
+++ clang/test/SemaCXX/literal-operators.cpp
@@ -3,46 +3,46 @@
 #include 
 
 struct tag {
-  void operator "" _tag_bad (const char *); // expected-error 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-07-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 538678.
rZhBoYao edited the summary of this revision.
rZhBoYao added a comment.

Defaults to on for C++23 only. Enable for all the language modes in another 
patch.


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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr25xx.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/CXX/drs/dr25xx.cpp
===
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,14 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
 
 namespace dr2516 { // dr2516: yes
// NB: reusing 1482 test
@@ -13,9 +23,13 @@
 
 namespace dr2518 { // dr2518: 17
 
+#if __cplusplus >= 201103L
 template 
 void f(T t) {
   if constexpr (sizeof(T) != sizeof(int)) {
+#if __cplusplus < 201703L
+// expected-error@-2 {{constexpr if is a C++17 extension}}
+#endif
 static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
   }
 }
@@ -28,6 +42,9 @@
 template 
 struct S {
   static_assert(false); // expected-error {{static assertion failed}}
+#if __cplusplus < 201703L
+// expected-error@-2 {{'static_assert' with no message is a C++17 extension}}
+#endif
 };
 
 template <>
@@ -41,11 +58,28 @@
   S s2;
   S s3; // expected-note {{in instantiation of template class 'dr2518::S' requested here}}
 }
+#endif
 
 }
 
+namespace dr2521 { // dr2521: 17
+#if __cplusplus >= 202302L
+long double operator""  _\u03C0___(long double);
+// expected-warning@-1 {{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+// expected-warning@-2 {{user-defined literal suffixes containing '__' are reserved}}
+
+template  decltype(sizeof 0)
+operator""  _div();
+// expected-warning@-1 {{identifier '_div' preceded by space(s) in the literal operator declaration is deprecated}}
+
+using ::dr2521::operator"" _\u03C0___;
+using ::dr2521::operator""_div;
+// expected-warning@-2 {{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+#endif
+} // namespace dr2521
 
 namespace dr2565 { // dr2565: 16 open
+#if __cplusplus >= 202002L
   template
 concept C = requires (typename T::type x) {
   x + 1;
@@ -107,4 +141,5 @@
   // expected-error@-1{{static assertion failed}}
   // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
+#endif
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -502,13 +502,17 @@
 IdentifierInfo *II = Name.Identifier;
 ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
 SourceLocation Loc = Name.getEndLoc();
-if (isReservedInAllContexts(Status) &&
-!PP.getSourceManager().isInSystemHeader(Loc)) {
-  Diag(Loc, diag::warn_reserved_extern_symbol)
-  << II << static_cast(Status)
-  << FixItHint::CreateReplacement(
- Name.getSourceRange(),
- (StringRef("operator\"\"") + II->getName()).str());
+if (!PP.getSourceManager().isInSystemHeader(Loc)) {
+  if (auto Hint = FixItHint::CreateReplacement(
+  Name.getSourceRange(),
+  

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-16 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 532223.
rZhBoYao edited the summary of this revision.
rZhBoYao added a comment.

Depends on D153156 

PS: I'm going on a vacation for 2 weeks. See you guys in July :)


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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/IdentifierTable.h
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr25xx.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/CXX/drs/dr25xx.cpp
===
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,14 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
 
 namespace dr2516 { // dr2516: yes
// NB: reusing 1482 test
@@ -13,9 +23,13 @@
 
 namespace dr2518 { // dr2518: 17
 
+#if __cplusplus >= 201103L
 template 
 void f(T t) {
   if constexpr (sizeof(T) != sizeof(int)) {
+#if __cplusplus < 201703L
+// expected-error@-2 {{constexpr if is a C++17 extension}}
+#endif
 static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
   }
 }
@@ -28,6 +42,9 @@
 template 
 struct S {
   static_assert(false); // expected-error {{static assertion failed}}
+#if __cplusplus < 201703L
+// expected-error@-2 {{'static_assert' with no message is a C++17 extension}}
+#endif
 };
 
 template <>
@@ -41,10 +58,28 @@
   S s2;
   S s3; // expected-note {{in instantiation of template class 'dr2518::S' requested here}}
 }
+#endif
 
 }
 
+namespace dr2521 { // dr2521: 17
+#if __cplusplus >= 201103L
+long double operator""  _\u03C0___(long double);
+// expected-warning@-1 {{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+// expected-warning@-2 {{user-defined literal suffixes containing '__' are reserved}}
+
+template  decltype(sizeof 0)
+operator""  _div();
+// expected-warning@-1 {{identifier '_div' preceded by space(s) in the literal operator declaration is deprecated}}
+
+using ::dr2521::operator"" _\u03C0___;
+using ::dr2521::operator""_div;
+// expected-warning@-2 {{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+#endif
+} // namespace dr2521
+
 namespace dr2565 { // dr2565: 16 open
+#if __cplusplus >= 202002L
   template
 concept C = requires (typename T::type x) {
   x + 1;
@@ -106,4 +141,5 @@
   // expected-error@-1{{static assertion failed}}
   // expected-note@-2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
+#endif
 }
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -501,13 +501,17 @@
 IdentifierInfo *II = Name.Identifier;
 ReservedIdentifierStatus Status = II->isReserved(PP.getLangOpts());
 SourceLocation Loc = Name.getEndLoc();
-if (isReservedInAllContexts(Status) &&
-!PP.getSourceManager().isInSystemHeader(Loc)) {
-  Diag(Loc, diag::warn_reserved_extern_symbol)
-  << II << static_cast(Status)
-  << FixItHint::CreateReplacement(
- Name.getSourceRange(),
- (StringRef("operator\"\"") + II->getName()).str());
+if (!PP.getSourceManager().isInSystemHeader(Loc)) {
+  if (auto Hint = FixItHint::CreateReplacement(
+  

[PATCH] D153156: [Clang] CWG1473: do not err on the lack of space after operator""

2023-06-16 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: Endill, aaron.ballman.
Herald added a subscriber: jvesely.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

[Clang] CWG1473: do not err on the lack of space after operator""

and fix tests for upcoming CWG2521 deprecation warning.

Side note: GCC stopped diagnosing this since GCC 4.9


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153156

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/lib/Lex/Lexer.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p11.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p3.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p4.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p5.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p6.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p7.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p8.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p9.cpp
  clang/test/CXX/over/over.oper/over.literal/p2.cpp
  clang/test/CXX/over/over.oper/over.literal/p3.cpp
  clang/test/CXX/over/over.oper/over.literal/p5.cpp
  clang/test/CXX/over/over.oper/over.literal/p6.cpp
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CXX/over/over.oper/over.literal/p8.cpp
  clang/test/CodeGenCXX/cxx11-user-defined-literal.cpp
  clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
  clang/test/FixIt/fixit-c++11.cpp
  clang/test/OpenMP/amdgcn_ldbl_check.cpp
  clang/test/PCH/cxx11-user-defined-literals.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/Parser/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals-unused.cpp
  clang/test/SemaCXX/cxx11-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1y-user-defined-literals.cpp
  clang/test/SemaCXX/cxx1z-user-defined-literals.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx98-compat.cpp
  clang/test/SemaCXX/literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
  clang/test/SemaCXX/reserved-identifier.cpp
  clang/test/SemaCXX/warn-xor-as-pow.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
@@ -8645,7 +8645,7 @@
 https://cplusplus.github.io/CWG/issues/1473.html;>1473
 CD3
 Syntax of literal-operator-id
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/1474.html;>1474
Index: clang/test/SemaCXX/warn-xor-as-pow.cpp
===
--- clang/test/SemaCXX/warn-xor-as-pow.cpp
+++ clang/test/SemaCXX/warn-xor-as-pow.cpp
@@ -19,10 +19,10 @@
 #define flexor 7
 
 #ifdef __cplusplus
-constexpr long long operator"" _xor(unsigned long long v) { return v; }
+constexpr long long operator""_xor(unsigned long long v) { return v; }
 
-constexpr long long operator"" _0b(unsigned long long v) { return v; }
-constexpr long long operator"" _0X(unsigned long long v) { return v; }
+constexpr long long operator""_0b(unsigned long long v) { return v; }
+constexpr long long operator""_0X(unsigned long long v) { return v; }
 #else
 #define xor ^ // iso646.h
 #endif
Index: clang/test/SemaCXX/reserved-identifier.cpp
===
--- clang/test/SemaCXX/reserved-identifier.cpp
+++ clang/test/SemaCXX/reserved-identifier.cpp
@@ -89,7 +89,7 @@
 long double sacrebleu = operator"" _SacreBleu(1.2); // expected-warning {{identifier '_SacreBleu' is reserved because it starts with '_' followed by a capital letter}}
 long double sangbleu = operator""_SacreBleu(1.2);   // no-warning
 
-void operator"" _lowercase(unsigned long long); // no-warning
+void operator""_lowercase(unsigned long long); // no-warning
 void operator""_lowercase(unsigned long long); // no-warning
 
 struct _BarbeRouge { // expected-warning {{identifier '_BarbeRouge' is reserved because it starts with '_' followed by a capital letter}}
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator ""bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
Index: clang/test/SemaCXX/literal-operators.cpp

[PATCH] D150023: [ABI] [C++20] [Modules] Don't generate vtable if the class is defined in other module unit

2023-06-14 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

> Looks like this breaks check-clang on Mac: 
> http://45.33.8.238/macm1/62779/step_7.txt

Same here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D150023

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


[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-13 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:411
+  "identifier '%0' preceded by space(s) in the literal operator declaration "
+  "is deprecated">, InGroup, DefaultIgnore;
 def warn_reserved_module_name : Warning<

aaron.ballman wrote:
> Oye, I'm of two minds about `DefaultIgnore`.
> 
> On the one hand, this is going to fire *a lot*: 
> https://sourcegraph.com/search?q=context:global+operator%5B%5B:space:%5D%5D*%5C%22%5C%22%5B%5B:space:%5D%5D%5BA-Za-z0-9_%5D%2B=regexp=yes=1=repo
> 
> On the other hand, if we don't warn about it being deprecated, users won't 
> know about it, which makes it harder to do anything about it the longer we 
> silently allow it. (We have plenty of experience with this particular flavor 
> of pain.)
> 
> I think we should warn about this by default. It's under its own warning 
> group, so users who want to ignore the warning and live dangerously can do 
> so. And it will be silenced in system headers automatically, so issuing the 
> diagnostic should generally be actionable for users.
I'm thinking the same after seeing [[ 
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2863r0.html#D.9 | 
P2863R0 § 6.9 ]]

However, a lot of tests are written in the deprecated way. I think a patch 
removing all the whitespaces only preceding this one is needed, to not clutter 
up this one.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:16448
 = FnDecl->getDeclName().getCXXLiteralIdentifier()->getName();
-  if (LiteralName[0] != '_' &&
+  if ((LiteralName[0] != '_' || LiteralName.contains("__")) &&
   !getSourceManager().isInSystemHeader(FnDecl->getLocation())) {

aaron.ballman wrote:
> I think we should use `IdentifierInfo::isReserved()` to determine why it's 
> reserved.
Totally. But I think we need another function, maybe isReservedLiteralSuffixId, 
since the rule for `literal suffix identifier`s is very different from that for 
"identifiers appearing as a token or preprocessing-token".



Comment at: clang/lib/Sema/SemaExprCXX.cpp:512-517
+  Diag(Loc, diag::warn_deprecated_literal_operator_id)
+  << II->getName()
   << FixItHint::CreateReplacement(
  Name.getSourceRange(),
  (StringRef("operator\"\"") + II->getName()).str());
 }

aaron.ballman wrote:
> Hmmm this means we're issuing two diagnostics -- missing an `else` here?
Does it have to be one or the other?

For example:
```
long double operator""  _KM(long double); // only warn reserved identifier
```
After replacing the identifier with km and recompile,
now there would be a new warning that was not previously shown,
which may be quite frustrating.

-
Oh wait, issuing two fixit hint seems to be very bad!






Comment at: clang/test/CXX/drs/dr17xx.cpp:129
   float operator ""_E(const char *);
   // expected-error@+2 {{invalid suffix on literal; C++11 requires a space 
between literal and identifier}}
+  // expected-warning@+1 {{user-defined literal suffixes containing '__' or 
not starting with '_' are reserved; no literal will invoke this operator}}

aaron.ballman wrote:
> So we give an error if there's not a space, but then give a deprecation 
> warning when there is a space?
I found it very confusing when editing the next line. After some research, I 
think that came from [[ https://timsong-cpp.github.io/cppwp/n3337/over.literal 
| C++11 over.literal ]]. But the rule should have long been superseded by [[ 
http://wg21.link/cwg1473 |CWG1473 ]] right? Since DRs are applied retroactively.

Additionally, GCC doesn't warn on this. Should we retire this error?



Comment at: clang/test/CXX/drs/dr25xx.cpp:71
+// expected-warning@+2 {{identifier '_π___' preceded by space(s) in the 
literal operator declaration is deprecated}}
+// expected-warning@+1 {{user-defined literal suffixes containing '__' or not 
starting with '_' are reserved}}
+long double operator""  _\u03C0___(long double);

Endill wrote:
> Is it possible to put expected directive after the code, like we do in 
> majority of existing tests? This means using only negative line offsets after 
> `@`
Will do


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

https://reviews.llvm.org/D152632

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


[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-11 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 530304.
rZhBoYao added a comment.

Overhaul for `dr25xx.cpp`.

For each test case, tried to support as many language modes as possible.
Not sure what those `-triple x86_64-unknown-unknown` are for? I leave them 
there nonetheless.

`-Wdeprecated-literal-operator` is under `-Wdeprecated` which is not under 
`-Wpedantic` so is not triggered by `-pedantic-errors`. Does this need change? 
I imagine it would be pretty disruptive.  On the other hand, pedantic users 
might care about deprecation 樂️.


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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" bar(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/Parser/cxx0x-literal-operators.cpp
===
--- clang/test/Parser/cxx0x-literal-operators.cpp
+++ clang/test/Parser/cxx0x-literal-operators.cpp
@@ -3,6 +3,6 @@
 void operator "" (const char *); // expected-error {{expected identifier}}
 void operator "k" foo(const char *); // \
   expected-error {{string literal after 'operator' must be '""'}} \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" tester (const char *); // \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
-void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
 
 template
 void f() {
Index: clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
-void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" p31(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" _p31(long double);
-long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 
 float hexfloat = 0x1p31; // 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-11 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 530292.
rZhBoYao added a comment.

Addressed comments.
Thanks for letting me know how to structure tests for DRs.


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

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/drs/dr25xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" bar(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/Parser/cxx0x-literal-operators.cpp
===
--- clang/test/Parser/cxx0x-literal-operators.cpp
+++ clang/test/Parser/cxx0x-literal-operators.cpp
@@ -3,6 +3,6 @@
 void operator "" (const char *); // expected-error {{expected identifier}}
 void operator "k" foo(const char *); // \
   expected-error {{string literal after 'operator' must be '""'}} \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" tester (const char *); // \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
-void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
 
 template
 void f() {
Index: clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
-void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" p31(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" _p31(long double);
-long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 
 float hexfloat = 0x1p31; // allow hexfloats
Index: clang/test/CXX/drs/dr25xx.cpp
===
--- clang/test/CXX/drs/dr25xx.cpp
+++ clang/test/CXX/drs/dr25xx.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -Wdeprecated-literal-operator
+// 

[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a reviewer: clang-language-wg.
rZhBoYao added a comment.

Few questions:
I think this applies to all the language modes?
Somehow, https://wg21.link/CWG2521 is not redirecting to 
https://cplusplus.github.io/CWG/issues/2521.html. Is this normal?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152632

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


[PATCH] D152632: [Clang] Add warnings for CWG2521

2023-06-10 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added a reviewer: serge-sans-paille.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

1. Teach -Wuser-defined-literals to warn on using double underscores in literal 
suffix identifiers.
2. Add -Wdeprecated-literal-operator to warn about the use of the first grammar 
production of literal-operator-id, which defaults to off.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152632

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/drs/dr17xx.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p1.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
  clang/test/Parser/cxx0x-literal-operators.cpp
  clang/test/SemaCXX/deprecated-literal-operator.cpp
  clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.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
@@ -14933,7 +14933,7 @@
 https://cplusplus.github.io/CWG/issues/2521.html;>2521
 DR
 User-defined literals and reserved identifiers
-Unknown
+Clang 17
   
   
 https://cplusplus.github.io/CWG/issues/2522.html;>2522
Index: clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
===
--- clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
+++ clang/test/SemaCXX/no-warn-user-defined-literals-in-system-headers.cpp
@@ -2,4 +2,4 @@
 
 #include 
 
-void operator "" bar(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" bar(long double); // expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/SemaCXX/deprecated-literal-operator.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/deprecated-literal-operator.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++23 %s -verify -Wdeprecated-literal-operator
+// RUN: %clang_cc1 -std=c++23 %s -verify -Wdeprecated
+
+namespace depr {
+
+decltype(sizeof 0) operator ""  _\u{3C0}___(long double); // \
+expected-warning{{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}} \
+expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
+
+template  consteval auto
+operator""   _div() { return (... / (Chars - '0')); } // OK, deprecated \
+expected-warning{{identifier '_div' preceded by space(s) in the literal operator declaration is deprecated}}
+
+} // namespace depr
+
+using depr::operator"" _\u{3C0}___, depr::operator""_div; // \
+expected-warning{{identifier '_π___' preceded by space(s) in the literal operator declaration is deprecated}}
+
+[[maybe_unused]] constexpr auto div = 841_div;
Index: clang/test/Parser/cxx0x-literal-operators.cpp
===
--- clang/test/Parser/cxx0x-literal-operators.cpp
+++ clang/test/Parser/cxx0x-literal-operators.cpp
@@ -3,6 +3,6 @@
 void operator "" (const char *); // expected-error {{expected identifier}}
 void operator "k" foo(const char *); // \
   expected-error {{string literal after 'operator' must be '""'}} \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
 void operator "" tester (const char *); // \
-  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+  expected-warning{{user-defined literal suffixes containing '__' or not starting with '_' are reserved}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
===
--- clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
-void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes containing '__' or not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal 

[PATCH] D139586: [Clang][C++23] Lifetime extension in range-based for loops

2023-05-15 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao abandoned this revision.
rZhBoYao added a comment.

In D139586#4324857 , @cor3ntin wrote:

> @rZhBoYao are you still working on this? Thanks!

No. Sorry that I don't have the capacity to work on this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139586

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


[PATCH] D139586: [Clang][C++23] Lifetime extension in range-based for loops

2022-12-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Consider:

  struct T {
const int *begin() const;
const int *end()   const;
T () [[clang::lifetimebound]];
T t();
  };
  
  const T (const T  [[clang::lifetimebound]]) { return t; }
  T g();
  
  void foo() {
for (auto e : f1(g())) {}
for (auto e : g().t().t().r()) {}
  }

The first __range1:

  | | `-VarDecl 0x11e901358  col:17 implicit used __range1 
'const T &' cinit
  | |   `-ExprWithCleanups 0x11e9015b8  'const T':'const T' 
lvalue
  | | `-CallExpr 0x11e9010b0  'const T':'const T' lvalue
  | |   |-ImplicitCastExpr 0x11e901098  'const T &(*)(const T &)' 

  | |   | `-DeclRefExpr 0x11e901018  'const T &(const T &)' lvalue 
Function 0x11e900a48 'f1' 'const T &(const T &)'
  | |   `-MaterializeTemporaryExpr 0x11e9010f0  'const 
T':'const T' lvalue extended by Var 0x11e901358 '__range1' 'const T &'
  | | `-ImplicitCastExpr 0x11e9010d8  'const T':'const 
T' 
  | |   `-CallExpr 0x11e900ec0  'T':'T'
  | | `-ImplicitCastExpr 0x11e900ea8  'T (*)()' 

  | |   `-DeclRefExpr 0x11e900e30  'T ()' lvalue Function 
0x11e900bd0 'g' 'T ()'

g() is extended by __range1.

The second __range1:

  | `-VarDecl 0x11e9040a0  col:17 implicit used __range1 'T &' 
cinit
  |   `-ExprWithCleanups 0x11e904338  'T':'T' lvalue
  | `-CXXMemberCallExpr 0x11e903f68  'T':'T' lvalue
  |   `-MemberExpr 0x11e903f38  '' .r 0x11e900638
  | `-MaterializeTemporaryExpr 0x11e903f20  'T':'T' 
xvalue extended by Var 0x11e9040a0 '__range1' 'T &'
  |   `-CXXMemberCallExpr 0x11e903f00  'T':'T'
  | `-MemberExpr 0x11e903ed0  '' .t 0x11e900780
  |   `-MaterializeTemporaryExpr 0x11e903eb8  
'T':'T' xvalue extended by Var 0x11e9040a0 '__range1' 'T &'
  | `-CXXMemberCallExpr 0x11e903e68  'T':'T'
  |   `-MemberExpr 0x11e903e38  '' .t 0x11e900780
  | `-MaterializeTemporaryExpr 0x11e903e20  
'T':'T' xvalue extended by Var 0x11e9040a0 '__range1' 'T &'
  |   `-CallExpr 0x11e903e00  'T':'T'
  | `-ImplicitCastExpr 0x11e903de8  'T (*)()' 

  |   `-DeclRefExpr 0x11e903dc8  'T ()' lvalue 
Function 0x11e900bd0 'g' 'T ()'

g() and 2 t()'s are extended by __range1.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139586

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


[PATCH] D139586: [Clang][C++23] Lifetime extension in range-based for loops

2022-12-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added a reviewer: clang-language-wg.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Implemented the C++23 paper P2718R0


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139586

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Decl.h
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1533,7 +1533,7 @@
 
   Lifetime extension in range-based for loops
   https://wg21.link/P2718R0;>P2718R0
-  No
+  Clang 16
 
 
 
Index: clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
===
--- clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify=expected,pre-cxx2b %s
+// RUN: %clang_cc1 -std=c++14 -verify=expected,pre-cxx2b %s
+// RUN: %clang_cc1 -std=c++17 -verify=expected,pre-cxx2b %s
+// RUN: %clang_cc1 -std=c++2b -verify %s
 
 struct pr12960 {
   int begin;
@@ -342,3 +343,19 @@
 for (auto x : f) {} // expected-error {{invalid range expression of type 'NF::F'; no viable 'end' function available}}
   }
 }
+
+namespace p2718r0 {
+struct T {
+  const int *begin() const;
+  const int *end()   const;
+  T () [[clang::lifetimebound]];
+};
+
+const T (const T  [[clang::lifetimebound]]) { return t; }
+T g();
+
+void foo() {
+  for (auto e : f1(g())) {} // pre-cxx2b-warning {{temporary implicitly bound to local reference will be destroyed at the end of the full-expression}}
+  for (auto e : g().r()) {} // pre-cxx2b-warning {{temporary implicitly bound to local reference will be destroyed at the end of the full-expression}}
+}
+}
Index: clang/lib/Sema/SemaStmt.cpp
===
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -2529,6 +2529,7 @@
   VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,
Context.getAutoRRefDeductType(),
std::string("__range") + DepthStr);
+  RangeVar->setCXXRangeVar(true);
   if (FinishForRangeVarDecl(*this, RangeVar, Range, RangeLoc,
 diag::err_for_range_deduction_failure)) {
 ActOnInitializerError(LoopVar);
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -6851,6 +6851,7 @@
 /// the initializer are included.
 struct IndirectLocalPathEntry {
   enum EntryKind {
+CXX2bForRangeInit,
 DefaultInit,
 AddressOf,
 VarInit,
@@ -7188,6 +7189,23 @@
   {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
   Init = DIE->getExpr();
 }
+
+if (auto *CE = dyn_cast(Init);
+CE && !Path.empty() &&
+Path.front().Kind == IndirectLocalPathEntry::CXX2bForRangeInit) {
+  if (EnableLifetimeWarnings)
+handleGslAnnotatedTypes(Path, Init, Visit);
+  visitLifetimeBoundArguments(Path, Init, Visit);
+  if (auto *ME = dyn_cast(CE->getCallee())) {
+Init = ME->getBase();
+  } else {
+for (auto *RSE : CE->getRawSubExprs())
+  if (auto *MTE = dyn_cast(RSE))
+if (Visit(Path, Local(MTE), RK))
+  visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit,
+   true, EnableLifetimeWarnings);
+  }
+}
   } while (Init != Old);
 
   if (auto *MTE = dyn_cast(Init)) {
@@ -7356,6 +7374,24 @@
 
   Init = CE->getSubExpr();
 }
+
+if (auto *CE = dyn_cast(Init);
+CE && !Path.empty() &&
+Path.front().Kind == IndirectLocalPathEntry::CXX2bForRangeInit) {
+  if (EnableLifetimeWarnings)
+handleGslAnnotatedTypes(Path, Init, Visit);
+  visitLifetimeBoundArguments(Path, Init, Visit);
+  if (auto *ME = dyn_cast(CE->getCallee())) {
+visitLocalsRetainedByReferenceBinding(Path, ME->getBase(),
+  RK_ReferenceBinding, Visit,
+  EnableLifetimeWarnings);
+  } else {
+for (auto *RSE : CE->getRawSubExprs())
+  if (auto *MTE = dyn_cast(RSE))
+visitLocalsRetainedByReferenceBinding(
+Path, MTE, RK_ReferenceBinding, Visit, EnableLifetimeWarnings);
+  }
+}
   } while (Old != Init);
 
   // 

[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-11 Thread PoYao Chang via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG50b1faf5c188: [Clang] CWG 1394: Incomplete types as 
parameters of deleted functions (authored by rZhBoYao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122981

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.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
@@ -8178,7 +8178,7 @@
 https://wg21.link/cwg1394;>1394
 CD3
 Incomplete types as parameters of deleted functions
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg1395;>1395
Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17379,6 +17379,21 @@
   }
 }
 
+void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc,
+   FnBodyKind BodyKind) {
+  switch (BodyKind) {
+  case FnBodyKind::Delete:
+SetDeclDeleted(D, Loc);
+break;
+  case FnBodyKind::Default:
+SetDeclDefaulted(D, Loc);
+break;
+  case FnBodyKind::Other:
+llvm_unreachable(
+"Parsed function body should be '= delete;' or '= default;'");
+  }
+}
+
 bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
  const CXXMethodDecl *Old) {
   const auto *NewFT = New->getType()->castAs();
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14271,7 +14271,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14290,7 +14290,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14466,7 +14466,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14555,11 +14556,11 @@
 }
   }
 
-  // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // The return type of a function definition must be complete (C99 6.9.1p3),
+  // unless the function is deleted (C++ specifc, C++ [dcl.fct.def.general]p2)
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14568,8 +14569,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (BodyKind != FnBodyKind::Delete)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);

[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-08 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

Revisiting @ChuanqiXu 's code suggestion...




Comment at: clang/include/clang/Sema/Sema.h:2899-2909
+/// C++ [dcl.fct.def.general]p1
+/// function-body:
+///   = delete ;
+///   = default ;
+Delete,
+Default,
+

erichkeane wrote:
> rZhBoYao wrote:
> > ChuanqiXu wrote:
> > > rZhBoYao wrote:
> > > > ChuanqiXu wrote:
> > > > > Agree to @erichkeane 
> > > > With all due respect, this code suggestion doesn't make any sense to 
> > > > me. My best guess is @ChuanqiXu was thinking the order specified by the 
> > > > grammar as noted in [[ 
> > > > https://eel.is/c++draft/dcl.fct.def.general#nt:function-body | 
> > > > dcl.fct.def.general p1 ]]. Even if that was the case, `CompoundStmt` is 
> > > > not quite right either. Also, differentiating `ctor-initializer[opt] 
> > > > compound-statement` and `function-try-block` is meaningless here, hence 
> > > > the name `Other`.
> > > > 
> > > > I adopted the same order as to how `Parser::ParseFunctionDefinition` 
> > > > has always been parsing `function-body`. The order is not significant 
> > > > in any meaningful way as each of the 4 grammar productions of 
> > > > `function-body` is VERY different and mutually exclusive. Putting 
> > > > `Delete` and `Default` upfront not only emphasizes the "specialness" of 
> > > > them but also conveys how we handle `function-body`.
> > > > 
> > > > What say you, @erichkeane ?
> > > Yeah, the order comes from the standard. I think the comment should be 
> > > consistent with the spec. And for the name, I agree `CompoundStmt` is not 
> > > accurate indeed... I thought Default should be a good name but there is 
> > > `Default` already. But I don't feel `Other` is good since the 
> > > compound-statement is much more common.
> > > 
> > > > Putting Delete and Default upfront not only emphasizes the 
> > > > "specialness" of them but also conveys how we handle function-body.
> > > 
> > > This don't makes sense. Generally, we would put common items in front. 
> > > And the order here shouldn't be related to the implementation.
> > > But I don't feel `Other` is good since the compound-statement is much 
> > > more common.
> > `Other` reads "not special like `Delete` and `Default`".
> > > This don't makes sense. Generally, we would put common items in front. 
> > > And the order here shouldn't be related to the implementation.
> > Think of it as a not-so-special else clause at the end of an if/else chain. 
> > We tend to process special cases upfront. It is only natural.
> > 
> > I'll await @erichkeane 's final verdict.
> >>Think of it as a not-so-special else clause at the end of an if/else chain. 
> >>We tend to process special cases upfront. It is only natural.
> 
> This was my understanding.  This is a single value that means 'not default 
> and not deleted'.  I think the idea of doing it in standards order is a 
> really good one, but have the top 2 just both result in `Other`, `Unknown`, 
> etc.  So something like:
> 
> ```
> //ctor-initializeropt compound-statement
> //function-try-block
> Unknown,
> //= default ;
> Default,
> //= delete ;
> Delete
> ```
> 
> BUT as this is not an 'ast' level flag, it is just for the purposes of 
> simplifying this call, I don't think it needs to conform that closely.
I actually don't know what you were trying to say here:
>  We don't yet part function-try-block yet.
>  FunctionTryBlock,
especially:
> We don't yet part function-try-block yet.

Nonetheless, I did my best to cater to your comment within reason, such as 
reordering enumerators to align with the C++ standard text.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-08 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 421589.
rZhBoYao marked 2 inline comments as done.
rZhBoYao set the repository for this revision to rG LLVM Github Monorepo.
rZhBoYao added a comment.

Reordered enumerators.

Does this look good to you, @ChuanqiXu ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122981

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.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
@@ -8178,7 +8178,7 @@
 https://wg21.link/cwg1394;>1394
 CD3
 Incomplete types as parameters of deleted functions
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg1395;>1395
Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17379,6 +17379,21 @@
   }
 }
 
+void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc,
+   FnBodyKind BodyKind) {
+  switch (BodyKind) {
+  case FnBodyKind::Delete:
+SetDeclDeleted(D, Loc);
+break;
+  case FnBodyKind::Default:
+SetDeclDefaulted(D, Loc);
+break;
+  case FnBodyKind::Other:
+llvm_unreachable(
+"Parsed function body should be '= delete;' or '= default;'");
+  }
+}
+
 bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
  const CXXMethodDecl *Old) {
   const auto *NewFT = New->getType()->castAs();
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14191,7 +14191,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14210,7 +14210,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14386,7 +14386,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14475,11 +14476,11 @@
 }
   }
 
-  // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // The return type of a function definition must be complete (C99 6.9.1p3),
+  // unless the function is deleted (C++ specifc, C++ [dcl.fct.def.general]p2)
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14488,8 +14489,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (BodyKind != FnBodyKind::Delete)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 

[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 2 inline comments as done.
rZhBoYao added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:2899-2909
+/// C++ [dcl.fct.def.general]p1
+/// function-body:
+///   = delete ;
+///   = default ;
+Delete,
+Default,
+

ChuanqiXu wrote:
> rZhBoYao wrote:
> > ChuanqiXu wrote:
> > > Agree to @erichkeane 
> > With all due respect, this code suggestion doesn't make any sense to me. My 
> > best guess is @ChuanqiXu was thinking the order specified by the grammar as 
> > noted in [[ https://eel.is/c++draft/dcl.fct.def.general#nt:function-body | 
> > dcl.fct.def.general p1 ]]. Even if that was the case, `CompoundStmt` is not 
> > quite right either. Also, differentiating `ctor-initializer[opt] 
> > compound-statement` and `function-try-block` is meaningless here, hence the 
> > name `Other`.
> > 
> > I adopted the same order as to how `Parser::ParseFunctionDefinition` has 
> > always been parsing `function-body`. The order is not significant in any 
> > meaningful way as each of the 4 grammar productions of `function-body` is 
> > VERY different and mutually exclusive. Putting `Delete` and `Default` 
> > upfront not only emphasizes the "specialness" of them but also conveys how 
> > we handle `function-body`.
> > 
> > What say you, @erichkeane ?
> Yeah, the order comes from the standard. I think the comment should be 
> consistent with the spec. And for the name, I agree `CompoundStmt` is not 
> accurate indeed... I thought Default should be a good name but there is 
> `Default` already. But I don't feel `Other` is good since the 
> compound-statement is much more common.
> 
> > Putting Delete and Default upfront not only emphasizes the "specialness" of 
> > them but also conveys how we handle function-body.
> 
> This don't makes sense. Generally, we would put common items in front. And 
> the order here shouldn't be related to the implementation.
> But I don't feel `Other` is good since the compound-statement is much more 
> common.
`Other` reads "not special like `Delete` and `Default`".
> This don't makes sense. Generally, we would put common items in front. And 
> the order here shouldn't be related to the implementation.
Think of it as a not-so-special else clause at the end of an if/else chain. We 
tend to process special cases upfront. It is only natural.

I'll await @erichkeane 's final verdict.


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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked an inline comment as done.
rZhBoYao added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:2899-2909
+/// C++ [dcl.fct.def.general]p1
+/// function-body:
+///   = delete ;
+///   = default ;
+Delete,
+Default,
+

ChuanqiXu wrote:
> Agree to @erichkeane 
With all due respect, this code suggestion doesn't make any sense to me. My 
best guess is @ChuanqiXu was thinking the order specified by the grammar as 
noted in [[ https://eel.is/c++draft/dcl.fct.def.general#nt:function-body | 
dcl.fct.def.general p1 ]]. Even if that was the case, `CompoundStmt` is not 
quite right either. Also, differentiating `ctor-initializer[opt] 
compound-statement` and `function-try-block` is meaningless here, hence the 
name `Other`.

I adopted the same order as to how `Parser::ParseFunctionDefinition` has always 
been parsing `function-body`. The order is not significant in any meaningful 
way as each of the 4 grammar productions of `function-body` is VERY different 
and mutually exclusive. Putting `Delete` and `Default` upfront not only 
emphasizes the "specialness" of them but also conveys how we handle 
`function-body`.

What say you, @erichkeane ?


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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 421345.
rZhBoYao added a comment.

Added release note.

Also, push to my repo to make sure the release note is correctly rendered:
https://github.com/poyaoc97/llvm-project/commit/1167f0fc6b91


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

https://reviews.llvm.org/D122981

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.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
@@ -8178,7 +8178,7 @@
 https://wg21.link/cwg1394;>1394
 CD3
 Incomplete types as parameters of deleted functions
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg1395;>1395
Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17379,6 +17379,21 @@
   }
 }
 
+void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc,
+   FnBodyKind BodyKind) {
+  switch (BodyKind) {
+  case FnBodyKind::Delete:
+SetDeclDeleted(D, Loc);
+break;
+  case FnBodyKind::Default:
+SetDeclDefaulted(D, Loc);
+break;
+  case FnBodyKind::Other:
+llvm_unreachable(
+"Parsed function body should be '= delete;' or '= default;'");
+  }
+}
+
 bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
  const CXXMethodDecl *Old) {
   const auto *NewFT = New->getType()->castAs();
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14185,7 +14185,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14204,7 +14204,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14380,7 +14380,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14469,11 +14470,11 @@
 }
   }
 
-  // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // The return type of a function definition must be complete (C99 6.9.1p3),
+  // unless the function is deleted (C++ specifc, C++ [dcl.fct.def.general]p2)
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14482,8 +14483,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (BodyKind != FnBodyKind::Delete)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function 

[PATCH] D122981: [Clang] CWG 1394: Incomplete types as parameters of deleted functions

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 421338.
rZhBoYao retitled this revision from "[Clang] Diagnose incomplete return/param 
types only when function is not deleted" to "[Clang] CWG 1394: Incomplete types 
as parameters of deleted functions".
rZhBoYao edited the summary of this revision.
rZhBoYao removed a reviewer: rtrieu.
rZhBoYao set the repository for this revision to rG LLVM Github Monorepo.
rZhBoYao added a comment.

Updating the status of CWG 1394 is the only change.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.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
@@ -8178,7 +8178,7 @@
 https://wg21.link/cwg1394;>1394
 CD3
 Incomplete types as parameters of deleted functions
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg1395;>1395
Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17379,6 +17379,21 @@
   }
 }
 
+void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc,
+   FnBodyKind BodyKind) {
+  switch (BodyKind) {
+  case FnBodyKind::Delete:
+SetDeclDeleted(D, Loc);
+break;
+  case FnBodyKind::Default:
+SetDeclDefaulted(D, Loc);
+break;
+  case FnBodyKind::Other:
+llvm_unreachable(
+"Parsed function body should be '= delete;' or '= default;'");
+  }
+}
+
 bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
  const CXXMethodDecl *Old) {
   const auto *NewFT = New->getType()->castAs();
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14185,7 +14185,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14204,7 +14204,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14380,7 +14380,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14469,11 +14470,11 @@
 }
   }
 
-  // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // The return type of a function definition must be complete (C99 6.9.1p3),
+  // unless the function is deleted (C++ specifc, C++ [dcl.fct.def.general]p2)
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14482,8 +14483,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-

[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 421328.
rZhBoYao marked 5 inline comments as done.
rZhBoYao added a comment.

Removed member function test cases and addressed comments,
which includes:

1. Sema::SetFunctionBodyKind
2. Change enum names
3. Be clear about delete being C++ specific.


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

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp

Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17379,6 +17379,21 @@
   }
 }
 
+void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc,
+   FnBodyKind BodyKind) {
+  switch (BodyKind) {
+  case FnBodyKind::Delete:
+SetDeclDeleted(D, Loc);
+break;
+  case FnBodyKind::Default:
+SetDeclDefaulted(D, Loc);
+break;
+  case FnBodyKind::Other:
+llvm_unreachable(
+"Parsed function body should be '= delete;' or '= default;'");
+  }
+}
+
 bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
  const CXXMethodDecl *Old) {
   const auto *NewFT = New->getType()->castAs();
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14185,7 +14185,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14204,7 +14204,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14380,7 +14380,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14469,11 +14470,11 @@
 }
   }
 
-  // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // The return type of a function definition must be complete (C99 6.9.1p3),
+  // unless the function is deleted (C++ specifc, C++ [dcl.fct.def.general]p2)
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14482,8 +14483,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (BodyKind != FnBodyKind::Delete)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function to the current
   // scope.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1299,6 +1299,41 @@
   ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
  Scope::CompoundStmtScope);
 
+  // Parse function body 

[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked an inline comment as done.
rZhBoYao added inline comments.



Comment at: clang/lib/Parse/Parser.cpp:1306
+  bool Delete =
+  Tok.is(tok::equal) && NextToken().is(tok::kw_delete) ? true : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,

rZhBoYao wrote:
> erichkeane wrote:
> > rZhBoYao wrote:
> > > erichkeane wrote:
> > > > I'm not sure about doing this 'look ahead' here, this feels dangerous 
> > > > to me.  First, does this work with comments?  Second, it seems we 
> > > > wouldn't normally look at 'deleted' if SkipBody.ShouldSkip (see below 
> > > > with the early exit)?
> > > > 
> > > > Next I'm not a fan of double-parsing these tokens with this lookahead.  
> > > > I wonder, if we should move hte logic from ~1334 and 1338 up here and 
> > > > calculate the 'deleted'/'defaulted' 'earlier', before we 
> > > > 'actOnStartOfFunctionDef`.  
> > > > 
> > > > This would result in us being able to instead change the signature of 
> > > > ActOnStartOfFunctionDef to take some enum as to whether it is 
> > > > deleted/defaulted, AND create the function decl as deleted/defaulted 
> > > > 'in place' (or, at least, call SetDeclDeleted or SetDeclDefaulted 
> > > > immediately).
> > > > 
> > > > 
> > > > 
> > > > 
> > > > I'm not sure about doing this 'look ahead' here, this feels dangerous 
> > > > to me. First, does this work with comments?
> > > Yes, it returns a normal token after phase 5, so comments are long gone.
> > > 
> > > > Second, it seems we wouldn't normally look at 'deleted' if 
> > > > SkipBody.ShouldSkip (see below with the early exit)?
> > > SkipBody.ShouldSkip is an output parameter of `ActOnStartOfFunctionDef`. 
> > > We need to either look ahead or consume "delete" before entering 
> > > `ActOnStartOfFunctionDef` anyway.
> > > 
> > > > Next I'm not a fan of double-parsing these tokens with this lookahead.
> > > It does look weird. Consume them I will. Updated diff coming.
> > > 
> > > > AND create the function decl as deleted/defaulted 'in place' (or, at 
> > > > least, call SetDeclDeleted or SetDeclDefaulted immediately).
> > > SetDecl{Deleted | Defaulted} needs KWLoc tho. I haven't thought of a way 
> > > of doing that "in place" inside `ActOnStartOfFunctionDef`.
> > My point is: do that parsing in this function BEFORE the call to 
> > ActOnStartOfFunctionDef?
> > 
> > Alternatively, we could add a function to Sema to 
> > 'ActOnFunctionDefinition(DefType)' and move this diagnostic THERE instead 
> > of ActOnStartofFunctionDef, and call it AFTER we have handled the '= 
> > delete/=default/etc'.
> > do that parsing in this function BEFORE the call to ActOnStartOfFunctionDef?
> But we need Decl *Res returned by ActOnStartOfFunctionDef.
> 
> I did try to factor out the diagnostic right after `ActOnFunctionDefinition` 
> and 27 tests were failing.
> Furthermore, we are not the only caller of `ActOnFunctionDefinition`.
I meant to say `ActOnStartOfFunctionDef`.


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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 421305.
rZhBoYao added a comment.

Handling of eagerly parsed deleted or defaulted function must happen AFTER 
`D.complete(Res);`.

A nice looking diff: 
https://github.com/poyaoc97/llvm-project/commit/dc37a262582f6a2d8143c6f1f586dc657b4b5311


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

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp

Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 4{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
+
+struct C {
+  Incomplete f(Incomplete) = delete; // well-formed
+  Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+  // expected-error{{variable has incomplete type 'Incomplete'}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14185,7 +14185,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, FnBodyKind BodyKind) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14204,7 +14204,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, BodyKind);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14380,7 +14380,8 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody,
+FnBodyKind BodyKind) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14470,10 +14471,11 @@
   }
 
   // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // unless the function is deleted
+  // (C99 6.9.1p3, C++ [dcl.fct.def.general]p2).
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && BodyKind != FnBodyKind::EqDelete &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14482,8 +14484,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (BodyKind != FnBodyKind::EqDelete)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function to the current
   // scope.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1299,6 +1299,41 @@
   ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
  Scope::CompoundStmtScope);
 
+  // Parse function body eagerly if it is either '= delete;' or '= default;' as
+  // ActOnStartOfFunctionDef needs to know whether the function is deleted.
+  Sema::FnBodyKind BodyKind = Sema::FnBodyKind::NotYetParsed;
+  SourceLocation KWLoc;
+  if (TryConsumeToken(tok::equal)) {
+assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
+
+if (TryConsumeToken(tok::kw_delete, KWLoc)) {
+  Diag(KWLoc, getLangOpts().CPlusPlus11
+  ? diag::warn_cxx98_compat_defaulted_deleted_function
+  : diag::ext_defaulted_deleted_function)
+  << 1 /* deleted */;
+  BodyKind = Sema::FnBodyKind::EqDelete;
+} else if 

[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 2 inline comments as done.
rZhBoYao added inline comments.



Comment at: clang/lib/Parse/Parser.cpp:1306
+  bool Delete =
+  Tok.is(tok::equal) && NextToken().is(tok::kw_delete) ? true : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,

erichkeane wrote:
> rZhBoYao wrote:
> > erichkeane wrote:
> > > I'm not sure about doing this 'look ahead' here, this feels dangerous to 
> > > me.  First, does this work with comments?  Second, it seems we wouldn't 
> > > normally look at 'deleted' if SkipBody.ShouldSkip (see below with the 
> > > early exit)?
> > > 
> > > Next I'm not a fan of double-parsing these tokens with this lookahead.  I 
> > > wonder, if we should move hte logic from ~1334 and 1338 up here and 
> > > calculate the 'deleted'/'defaulted' 'earlier', before we 
> > > 'actOnStartOfFunctionDef`.  
> > > 
> > > This would result in us being able to instead change the signature of 
> > > ActOnStartOfFunctionDef to take some enum as to whether it is 
> > > deleted/defaulted, AND create the function decl as deleted/defaulted 'in 
> > > place' (or, at least, call SetDeclDeleted or SetDeclDefaulted 
> > > immediately).
> > > 
> > > 
> > > 
> > > 
> > > I'm not sure about doing this 'look ahead' here, this feels dangerous to 
> > > me. First, does this work with comments?
> > Yes, it returns a normal token after phase 5, so comments are long gone.
> > 
> > > Second, it seems we wouldn't normally look at 'deleted' if 
> > > SkipBody.ShouldSkip (see below with the early exit)?
> > SkipBody.ShouldSkip is an output parameter of `ActOnStartOfFunctionDef`. We 
> > need to either look ahead or consume "delete" before entering 
> > `ActOnStartOfFunctionDef` anyway.
> > 
> > > Next I'm not a fan of double-parsing these tokens with this lookahead.
> > It does look weird. Consume them I will. Updated diff coming.
> > 
> > > AND create the function decl as deleted/defaulted 'in place' (or, at 
> > > least, call SetDeclDeleted or SetDeclDefaulted immediately).
> > SetDecl{Deleted | Defaulted} needs KWLoc tho. I haven't thought of a way of 
> > doing that "in place" inside `ActOnStartOfFunctionDef`.
> My point is: do that parsing in this function BEFORE the call to 
> ActOnStartOfFunctionDef?
> 
> Alternatively, we could add a function to Sema to 
> 'ActOnFunctionDefinition(DefType)' and move this diagnostic THERE instead of 
> ActOnStartofFunctionDef, and call it AFTER we have handled the '= 
> delete/=default/etc'.
> do that parsing in this function BEFORE the call to ActOnStartOfFunctionDef?
But we need Decl *Res returned by ActOnStartOfFunctionDef.

I did try to factor out the diagnostic right after `ActOnFunctionDefinition` 
and 27 tests were failing.
Furthermore, we are not the only caller of `ActOnFunctionDefinition`.


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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 3 inline comments as done.
rZhBoYao added inline comments.



Comment at: clang/lib/Parse/Parser.cpp:1306
+  bool Delete =
+  Tok.is(tok::equal) && NextToken().is(tok::kw_delete) ? true : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,

erichkeane wrote:
> I'm not sure about doing this 'look ahead' here, this feels dangerous to me.  
> First, does this work with comments?  Second, it seems we wouldn't normally 
> look at 'deleted' if SkipBody.ShouldSkip (see below with the early exit)?
> 
> Next I'm not a fan of double-parsing these tokens with this lookahead.  I 
> wonder, if we should move hte logic from ~1334 and 1338 up here and calculate 
> the 'deleted'/'defaulted' 'earlier', before we 'actOnStartOfFunctionDef`.  
> 
> This would result in us being able to instead change the signature of 
> ActOnStartOfFunctionDef to take some enum as to whether it is 
> deleted/defaulted, AND create the function decl as deleted/defaulted 'in 
> place' (or, at least, call SetDeclDeleted or SetDeclDefaulted immediately).
> 
> 
> 
> 
> I'm not sure about doing this 'look ahead' here, this feels dangerous to me. 
> First, does this work with comments?
Yes, it returns a normal token after phase 5, so comments are long gone.

> Second, it seems we wouldn't normally look at 'deleted' if 
> SkipBody.ShouldSkip (see below with the early exit)?
SkipBody.ShouldSkip is an output parameter of `ActOnStartOfFunctionDef`. We 
need to either look ahead or consume "delete" before entering 
`ActOnStartOfFunctionDef` anyway.

> Next I'm not a fan of double-parsing these tokens with this lookahead.
It does look weird. Consume them I will. Updated diff coming.

> AND create the function decl as deleted/defaulted 'in place' (or, at least, 
> call SetDeclDeleted or SetDeclDefaulted immediately).
SetDecl{Deleted | Defaulted} needs KWLoc tho. I haven't thought of a way of 
doing that "in place" inside `ActOnStartOfFunctionDef`.



Comment at: clang/lib/Sema/SemaDecl.cpp:14461
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && !FnDeleted &&
   RequireCompleteType(FD->getLocation(), ResultType,

erichkeane wrote:
> ChuanqiXu wrote:
> > rZhBoYao wrote:
> > > ChuanqiXu wrote:
> > > > I think we could remove the use of `FnDeleted` by the use of 
> > > > `FD->isDeleted()`. Also we should constrain the behavior only if std >= 
> > > > 11.
> > > I tried `FD->isDeleted()` at first only to find out it always returns 
> > > `false`. Looks like it's not handled until [[ 
> > > https://github.com/llvm/llvm-project/blob/634bf829a8d289371d5b5a50b787596124228898/clang/lib/Parse/Parser.cpp#L1342
> > >  | Parser.cpp:1342 ]]
> > > 
> > > Also, looks like deleted functions are implemented as an extension. A 
> > > warning is issued at [[ 
> > > https://github.com/llvm/llvm-project/blob/634bf829a8d289371d5b5a50b787596124228898/clang/lib/Parse/Parser.cpp#L1338-L1341
> > >  | Parser.cpp:1338 ]] if language mode < C++11
> > I see. My suggestion might be to defer the diagnose message after we set 
> > `FD->setDeletedAsWritten()`. I understand it might be harder. But the 
> > current implementation looks a little bit not good... (redundant variables 
> > and passing information by argument)
> I disagree on doing this for C++11 mode.  As we allow them as an extension, 
> we want this to work in the extension mode as well.
Thanks for the endorsement.


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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-06 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 420764.
rZhBoYao marked 2 inline comments as done.
rZhBoYao added a reviewer: erichkeane.
rZhBoYao added a comment.

I think an extra parameter is inevitable without complicating things too much.


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

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp

Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete; // expected-note 4{{forward declaration of 'Incomplete'}}
+Incomplete f(Incomplete) = delete; // well-formed
+Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+// expected-error{{variable has incomplete type 'Incomplete'}}
+
+struct C {
+  Incomplete f(Incomplete) = delete; // well-formed
+  Incomplete g(Incomplete) {}// expected-error{{incomplete result type 'Incomplete' in function definition}}\
+  // expected-error{{variable has incomplete type 'Incomplete'}}
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14185,7 +14185,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, bool FnDeleted) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14204,7 +14204,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, FnDeleted);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14380,7 +14380,7 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody, bool FnDeleted) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14470,10 +14470,11 @@
   }
 
   // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // unless the function is deleted
+  // (C99 6.9.1p3, C++ [dcl.fct.def.general]p2).
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && !FnDeleted &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14482,8 +14483,9 @@
 PushDeclContext(FnBodyScope, FD);
 
   // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (!FnDeleted)
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function to the current
   // scope.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1302,11 +1302,13 @@
   // Tell the actions module that we have entered a function definition with the
   // specified Declarator for the function.
   Sema::SkipBodyInfo SkipBody;
+  bool Delete =
+  Tok.is(tok::equal) && NextToken().is(tok::kw_delete) ? true : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
   TemplateInfo.TemplateParams
   ? *TemplateInfo.TemplateParams
   : MultiTemplateParamsArg(),
-  );
+  , Delete);
 
   if (SkipBody.ShouldSkip) {
 SkipFunctionBody();
@@ -1332,7 +1334,6 @@
   if (TryConsumeToken(tok::equal)) {
 assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
 
-bool Delete = false;
 SourceLocation KWLoc;
 if (TryConsumeToken(tok::kw_delete, KWLoc)) {
   

[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-05 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 2 inline comments as done.
rZhBoYao added inline comments.



Comment at: clang/lib/Parse/Parser.cpp:1339
 
 bool Delete = false;
 SourceLocation KWLoc;

I'm thinking should we merge `FnDeleted` and `Deleted` into one variable or 
leave it as is? On the one hand, `Deleted`'s scope is tight so very readable. 
On the other hand, it seems redundant.



Comment at: clang/lib/Parse/Parser.cpp:1346
 << 1 /* deleted */;
   Actions.SetDeclDeleted(Res, KWLoc);
   Delete = true;

`FunctionDecl::setDeletedAsWritten` not called until this `SetDeclDeleted` call.



Comment at: clang/lib/Sema/SemaDecl.cpp:14457
   // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // unless the function is deleted
+  // (C99 6.9.1p3, C++ [dcl.fct.def.general]p2).

ChuanqiXu wrote:
> 
I think the sentence is not yet complete there so I mimic the old one on the 
left.



Comment at: clang/lib/Sema/SemaDecl.cpp:14461
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && !FnDeleted &&
   RequireCompleteType(FD->getLocation(), ResultType,

ChuanqiXu wrote:
> I think we could remove the use of `FnDeleted` by the use of 
> `FD->isDeleted()`. Also we should constrain the behavior only if std >= 11.
I tried `FD->isDeleted()` at first only to find out it always returns `false`. 
Looks like it's not handled until [[ 
https://github.com/llvm/llvm-project/blob/634bf829a8d289371d5b5a50b787596124228898/clang/lib/Parse/Parser.cpp#L1342
 | Parser.cpp:1342 ]]

Also, looks like deleted functions are implemented as an extension. A warning 
is issued at [[ 
https://github.com/llvm/llvm-project/blob/634bf829a8d289371d5b5a50b787596124228898/clang/lib/Parse/Parser.cpp#L1338-L1341
 | Parser.cpp:1338 ]] if language mode < C++11


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122981

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


[PATCH] D122981: [Clang] Diagnose incomplete return/param types only when function is not deleted

2022-04-02 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: ChuanqiXu, rsmith.
rZhBoYao added a project: clang.
Herald added a project: All.
rZhBoYao requested review of this revision.
Herald added a subscriber: cfe-commits.

According to dcl.fct.def.general p2 
 and this 
,
 deleted functions with incomplete return types and parameter types are 
well-formed.

  struct Incomplete;   // expected-note{{forward declaration of 
'Incomplete'}}
  Incomplete f() = delete; // well-formed
  Incomplete g(Incomplete a) = delete; // well-formed
  Incomplete h() {}// expected-error{{incomplete result 
type 'Incomplete' in function definition}}

Inspired by this tweet 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122981

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/Parser.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp

Index: clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
===
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.general/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Incomplete;   // expected-note{{forward declaration of 'Incomplete'}}
+Incomplete f() = delete; // well-formed
+Incomplete g(Incomplete a) = delete; // well-formed
+Incomplete h() {}// expected-error{{incomplete result type 'Incomplete' in function definition}}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14169,7 +14169,7 @@
 Decl *
 Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator ,
   MultiTemplateParamsArg TemplateParameterLists,
-  SkipBodyInfo *SkipBody) {
+  SkipBodyInfo *SkipBody, bool FnDeleted) {
   assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
@@ -14188,7 +14188,7 @@
 
   D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
   Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
-  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
+  Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody, FnDeleted);
 
   if (!Bases.empty())
 ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases);
@@ -14364,7 +14364,7 @@
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
-SkipBodyInfo *SkipBody) {
+SkipBodyInfo *SkipBody, bool FnDeleted) {
   if (!D) {
 // Parsing the function declaration failed in some way. Push on a fake scope
 // anyway so we can try to parse the function body.
@@ -14454,10 +14454,11 @@
   }
 
   // The return type of a function definition must be complete
-  // (C99 6.9.1p3, C++ [dcl.fct]p6).
+  // unless the function is deleted
+  // (C99 6.9.1p3, C++ [dcl.fct.def.general]p2).
   QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
-  !FD->isInvalidDecl() &&
+  !FD->isInvalidDecl() && !FnDeleted &&
   RequireCompleteType(FD->getLocation(), ResultType,
   diag::err_func_def_incomplete_result))
 FD->setInvalidDecl();
@@ -14465,9 +14466,10 @@
   if (FnBodyScope)
 PushDeclContext(FnBodyScope, FD);
 
-  // Check the validity of our function parameters
-  CheckParmsForFunctionDef(FD->parameters(),
-   /*CheckParameterNames=*/true);
+  if (!FnDeleted)
+// Check the validity of our function parameters
+CheckParmsForFunctionDef(FD->parameters(),
+ /*CheckParameterNames=*/true);
 
   // Add non-parameter declarations already in the function to the current
   // scope.
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -1302,11 +1302,15 @@
   // Tell the actions module that we have entered a function definition with the
   // specified Declarator for the function.
   Sema::SkipBodyInfo SkipBody;
+  bool FnDeleted = GetLookAheadToken(0).getKind() == tok::equal &&
+   GetLookAheadToken(1).getKind() == tok::kw_delete
+   ? true
+   : false;
   Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
   

[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG355f1c75aa66: [Clang] Fix PR28101 (authored by rZhBoYao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115248

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in 
instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.SetIdentifier(Name.getAsIdentifierInfo(), Loc);
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -69,6 +69,9 @@
   like ``auto&`` or ``auto**`` were added. These constraints are now checked.
   This fixes  `Issue 53911 
`_
   and  `Issue 54443 `_.
+- Previously invalid member variables with template parameters would crash 
clang.
+  Now fixed by setting identifiers for them.
+  This fixes `Issue 28475 (PR28101) 
`_.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.SetIdentifier(Name.getAsIdentifierInfo(), Loc);
 }
 
 if (SS.isSet() && 

[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 417648.
rZhBoYao edited the summary of this revision.
rZhBoYao set the repository for this revision to rG LLVM Github Monorepo.
rZhBoYao added a comment.

Added an entry in release notes. Waiting for CI...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115248

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in 
instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.SetIdentifier(Name.getAsIdentifierInfo(), Loc);
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -69,6 +69,9 @@
   like ``auto&`` or ``auto**`` were added. These constraints are now checked.
   This fixes  `Issue 53911 
`_
   and  `Issue 54443 `_.
+- Previously invalid member variables with template parameters would crash 
clang.
+  Now fixed by setting identifiers for them.
+  This fixes `Issue 28475 (PR28101) 
`_.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  

[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao added a comment.

By 'release notes' do you mean a more detailed commit message?


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

https://reviews.llvm.org/D115248

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


[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 417632.
rZhBoYao marked 3 inline comments as done.
rZhBoYao added a comment.

This passes check-clang-semacxx on my machine.


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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation 
of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in 
instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.SetIdentifier(Name.getAsIdentifierInfo(), Loc);
 }
 
 if (SS.isSet() && !SS.isInvalid()) {


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error2{{member 'A' has the same name as its class}}
+};
+// Don't crash.
+A instantiate1() { return {nullptr}; } // expected-note{{in instantiation of template class 'A' requested here}}
+
+template  struct B {
+  B(void *) {}
+  T B{}; // expected-error{{member 'B' cannot have template arguments}}\
+  // expected-error2{{member 'B' has the same name as its class}}
+};
+// Don't crash.
+B instantiate2() { return {nullptr}; } // expected-note{{in instantiation of template class 'B' requested here}}
+
+template  struct S {};
+
+template  struct C {
+  C(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+// Don't crash.
+C instantiate3() { return {nullptr}; }
+
+template  typename U> class D {
+public:
+  D(void *) {}
+  T(D>) {} // expected-error{{member 'D' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error2{{member 'D' has the same name as its class}}
+};
+// Don't crash.
+D instantiate4() { return D(nullptr); } // expected-note{{in instantiation of template class 'D' requested here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.SetIdentifier(Name.getAsIdentifierInfo(), Loc);
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao marked 3 inline comments as done.
rZhBoYao added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:3430
   << D.getName().TemplateId->LAngleLoc;
+  if (cast(CurContext)->getDeclName() == Name)
+Diag(Loc, diag::err_member_name_of_class) << Name;

erichkeane wrote:
> I see we are diagnosing this ONLY inside of the case where it is a template.  
> Where is this caught when we are in the non-template case, why doesn't THAT 
> catch these cases, and what would it take to do so?
CheckCompletedCXXClass should catch diag::err_member_name_of_class. However, 
these FieldDecl have no name hence uncaught. Maybe we should set the identifier 
for this declarator here.



Comment at: clang/test/SemaCXX/PR28101.cpp:8
+
+#ifdef CASE_1
+

erichkeane wrote:
> This isn't necessary, the compiler in verify mode should see all errors.  I 
> see above at most 2 invocations of the compiler as necessary.
Instantiation of each of the 4 classes could crash on its own, so I thought I'd 
separate them into 4 invocations.



Comment at: clang/test/SemaCXX/PR28101.cpp:16
+
+A instantiate() { return {nullptr}; }
+

erichkeane wrote:
> How come there are no notes in this test that say 'in instantiation of...'?  
> I would expect those in at least some of these cases, right?
Because it was caught before instantiation and when instantiating the FieldDecl 
is gone after calling `D.setInvalidType();`. If I set the identifier for the 
FieldDecl and let `CheckCompletedCXXClass` handle the "has the same name as its 
class" error, there will be the "in instantiation of..." note.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115248

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


[PATCH] D115248: [Clang] Fix PR28101

2022-03-23 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 417504.
rZhBoYao set the repository for this revision to rG LLVM Github Monorepo.
rZhBoYao added a comment.

Diagnose "same name as its class" before setting the declarator invalid as 
otherwise it would not be diagnosed. This also aligns with gcc's behavior.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template  struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template  struct S {};
+
+template  struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U> class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+template  struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,9 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  if (cast(CurContext)->getDeclName() == Name)
+Diag(Loc, diag::err_member_name_of_class) << Name;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template  struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template  struct S {};
+
+template  struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U> class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}\
+  // expected-error{{member 'A' has the same name as its class}}
+};
+
+template  struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,9 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  if (cast(CurContext)->getDeclName() == Name)
+Diag(Loc, diag::err_member_name_of_class) << Name;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [Clang] Fix PR28101

2022-03-22 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 417475.
rZhBoYao added a comment.

Don't break template declarations.
re-clang-format


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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template  struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template  struct S {};
+
+template  struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U> class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}
+};
+
+template  struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template  struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template  struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template  struct S {};
+
+template  struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U> class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}
+};
+
+template  struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [Clang] Fix PR28101

2022-03-22 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 417461.
rZhBoYao retitled this revision from "[clang] Fix PR28101" to "[Clang] Fix 
PR28101".
rZhBoYao edited the summary of this revision.
rZhBoYao added a reviewer: cor3ntin.
rZhBoYao set the repository for this revision to rG LLVM Github Monorepo.
rZhBoYao added a comment.
Herald added a project: All.

The previous diff was indeed very specific and doesn't handle

  template 
  struct A {
A(void*) {}
T A{}; // expected-error{{member 'A' cannot have template arguments}}
  };
  
  A instantiate() { return {nullptr}; }

I have since realized the invalid decorator is the problem and the parentheses 
are insignificant. It's like:

  template  struct S {};
  int S{};

which gcc diagnoses to

> error: invalid declarator before '{' token

Then I found there was a new diagnostic added by D120881 
. So the fix is pretty straightforward at 
this point. I simply stand on the shoulder of the giant and set the invalid 
flag of the declarator.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/PR28101.cpp


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template 
+struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template 
+struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template 
+struct S {};
+
+template 
+struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U>
+class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template 
arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}
+};
+
+template 
+struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {


Index: clang/test/SemaCXX/PR28101.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/PR28101.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_3 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -DCASE_4 -std=c++17 %s
+
+// Don't crash.
+
+#ifdef CASE_1
+
+template 
+struct A {
+  A(void *) {}
+  T(A){}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_2
+
+template 
+struct A {
+  A(void *) {}
+  T A{}; // expected-error{{member 'A' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_3
+
+template 
+struct S {};
+
+template 
+struct A {
+  A(void *) {}
+  T S{}; // expected-error{{member 'S' cannot have template arguments}}
+};
+
+A instantiate() { return {nullptr}; }
+
+#elifdef CASE_4
+
+template  typename U>
+class A {
+public:
+  A(void *) {}
+  T(A>) {} // expected-error{{member 'A' cannot have template arguments}}\
+  // expected-error{{expected ';' at end of declaration list}}
+};
+
+template 
+struct S {};
+
+A foo() { return A(nullptr); }
+
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -3427,6 +3427,7 @@
   << SourceRange(D.getName().TemplateId->LAngleLoc,
  D.getName().TemplateId->RAngleLoc)
   << D.getName().TemplateId->LAngleLoc;
+  D.setInvalidType();
 }
 
 if (SS.isSet() && !SS.isInvalid()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [clang] Fix Bug 28101

2021-12-08 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 392774.
rZhBoYao edited the summary of this revision.
rZhBoYao added a comment.

I added a test. There were 17 module and PCH related failed tests on my local 
machine; however, when I ran the test on then ToT 

 the same 17 tests failed, but on GitHub 

 it does show 2 successful checks. So maybe it's something else.


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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp


Index: clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
===
--- clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
+++ clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
@@ -4,3 +4,13 @@
   template  virtual void g(C); // expected-error{{'virtual' cannot be 
specified on member function templates}}
   virtual void f();
 };
+
+template 
+class PR28101 {
+public:
+  PR28101(void *) {}
+  T(PR28101){}; // expected-error{{member 'PR28101' has the same name as 
its class}} \
+  // expected-error{{member 'PR28101' has the same name as its class}}
+};
+
+PR28101 foo() { return new int; } // expected-note{{in instantiation of 
template class 'PR28101' requested here}}
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6482,6 +6482,11 @@
 if (EllipsisLoc.isValid())
   DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
 
+if (getLangOpts().CPlusPlus && !D.getIdentifier() &&
+D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId &&
+D.getContext() == DeclaratorContext::Member)
+  D.SetIdentifier(D.getName().TemplateId->Name, D.getName().getBeginLoc());
+
 return;
   }
 


Index: clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
===
--- clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
+++ clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
@@ -4,3 +4,13 @@
   template  virtual void g(C); // expected-error{{'virtual' cannot be specified on member function templates}}
   virtual void f();
 };
+
+template 
+class PR28101 {
+public:
+  PR28101(void *) {}
+  T(PR28101){}; // expected-error{{member 'PR28101' has the same name as its class}} \
+  // expected-error{{member 'PR28101' has the same name as its class}}
+};
+
+PR28101 foo() { return new int; } // expected-note{{in instantiation of template class 'PR28101' requested here}}
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6482,6 +6482,11 @@
 if (EllipsisLoc.isValid())
   DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
 
+if (getLangOpts().CPlusPlus && !D.getIdentifier() &&
+D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId &&
+D.getContext() == DeclaratorContext::Member)
+  D.SetIdentifier(D.getName().TemplateId->Name, D.getName().getBeginLoc());
+
 return;
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [clang] Fix Bug 28101

2021-12-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao updated this revision to Diff 392399.

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

https://reviews.llvm.org/D115248

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15440,6 +15440,11 @@
 break;
   }
 }
+if (LLVM_UNLIKELY(!Pattern))
+  for (const auto *FD : ClassPattern->fields())
+if (Diags.hasErrorOccurred() && !FD->getIdentifier()) {
+  return ExprError();
+}
 assert(Pattern && "We must have set the Pattern!");
 
 if (!Pattern->hasInClassInitializer() ||
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6205,6 +6205,12 @@
 // is exited (and the declarator has been parsed).
 DeclScopeObj.EnterDeclaratorScope();
 }
+if (D.getContext() == DeclaratorContext::Member && D.hasName() &&
+!D.getIdentifier())
+  Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+   diag::err_expected_member_name_or_semi)
+  << (D.getDeclSpec().isEmpty() ? SourceRange()
+: D.getDeclSpec().getSourceRange());
   } else if (D.mayOmitIdentifier()) {
 // This could be something simple like "int" (in which case the declarator
 // portion is empty), if an abstract-declarator is allowed.


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15440,6 +15440,11 @@
 break;
   }
 }
+if (LLVM_UNLIKELY(!Pattern))
+  for (const auto *FD : ClassPattern->fields())
+if (Diags.hasErrorOccurred() && !FD->getIdentifier()) {
+  return ExprError();
+}
 assert(Pattern && "We must have set the Pattern!");
 
 if (!Pattern->hasInClassInitializer() ||
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6205,6 +6205,12 @@
 // is exited (and the declarator has been parsed).
 DeclScopeObj.EnterDeclaratorScope();
 }
+if (D.getContext() == DeclaratorContext::Member && D.hasName() &&
+!D.getIdentifier())
+  Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+   diag::err_expected_member_name_or_semi)
+  << (D.getDeclSpec().isEmpty() ? SourceRange()
+: D.getDeclSpec().getSourceRange());
   } else if (D.mayOmitIdentifier()) {
 // This could be something simple like "int" (in which case the declarator
 // portion is empty), if an abstract-declarator is allowed.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115248: [clang] Fix Bug 28101

2021-12-07 Thread PoYao Chang via Phabricator via cfe-commits
rZhBoYao created this revision.
rZhBoYao added reviewers: rsmith, aaron.ballman, erichkeane, v.g.vassilev, rnk.
rZhBoYao added a project: clang.
rZhBoYao requested review of this revision.
Herald added a subscriber: cfe-commits.

This should fix Bug 28101  where 
the culprit line is parsed as `FieldDecl 0x2136240  col:6 
'T':'T'`(why not `A` tho?).

I observed that GCC(trunk on godbolt.org) would issue: `:6:6: error: 
field 'int A::A' with same name as class`, which corresponds to clang's 
`diag::err_member_name_of_class`. But as the dumped AST shows, there is no name 
on the FieldDecl, and then I found clang would issue 
`diag::err_expected_member_name_or_semi` on `int (double) {};`, which resembles 
`T (A < T >) {};` so I went with this error.

I am ready to be corrected as I'm new to clang and this differs from GCC's 
behavior. Any guidance and comments would be appreciated.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115248

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15440,6 +15440,11 @@
 break;
   }
 }
+if (LLVM_UNLIKELY(!Pattern))
+  for (const auto *FD : ClassPattern->fields())
+if (Diags.hasErrorOccurred() && !FD->getIdentifier()) {
+  return ExprError();
+}
 assert(Pattern && "We must have set the Pattern!");
 
 if (!Pattern->hasInClassInitializer() ||
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6205,6 +6205,11 @@
 // is exited (and the declarator has been parsed).
 DeclScopeObj.EnterDeclaratorScope();
 }
+if (D.hasName() && !D.getIdentifier())
+  Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+   diag::err_expected_member_name_or_semi)
+  << (D.getDeclSpec().isEmpty() ? SourceRange()
+: D.getDeclSpec().getSourceRange());
   } else if (D.mayOmitIdentifier()) {
 // This could be something simple like "int" (in which case the declarator
 // portion is empty), if an abstract-declarator is allowed.


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -15440,6 +15440,11 @@
 break;
   }
 }
+if (LLVM_UNLIKELY(!Pattern))
+  for (const auto *FD : ClassPattern->fields())
+if (Diags.hasErrorOccurred() && !FD->getIdentifier()) {
+  return ExprError();
+}
 assert(Pattern && "We must have set the Pattern!");
 
 if (!Pattern->hasInClassInitializer() ||
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6205,6 +6205,11 @@
 // is exited (and the declarator has been parsed).
 DeclScopeObj.EnterDeclaratorScope();
 }
+if (D.hasName() && !D.getIdentifier())
+  Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+   diag::err_expected_member_name_or_semi)
+  << (D.getDeclSpec().isEmpty() ? SourceRange()
+: D.getDeclSpec().getSourceRange());
   } else if (D.mayOmitIdentifier()) {
 // This could be something simple like "int" (in which case the declarator
 // portion is empty), if an abstract-declarator is allowed.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits