[PATCH] D150001: [clang] Fix initializer_list matching failures with modules

2023-05-06 Thread Yingchi Long via Phabricator via cfe-commits
inclyc accepted this revision.
inclyc added a comment.
This revision is now accepted and ready to land.

I think this fix is simple and straightforward and resolved the problem 
mentioned on GH. However, please wait for #clang-language-wg 
 member's comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D150001

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


[PATCH] D143439: [RISCV] Add vendor-defined XTheadBb (basic bit-manipulation) extension

2023-02-13 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVISelLowering.cpp:320
+if (Subtarget.is64Bit())
+  setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_UNDEF}, MVT::i32, Custom);
+  }

inclyc wrote:
> And this one
Ah, this is my fault :(. There should be only 1 warning on line 315


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143439

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


[PATCH] D143439: [RISCV] Add vendor-defined XTheadBb (basic bit-manipulation) extension

2023-02-13 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: llvm/lib/Target/RISCV/RISCVISelLowering.cpp:315
+  if (Subtarget.hasVendorXTHeadBb()) {
+setOperationAction({ISD::CTLZ}, XLenVT, Legal);
+

It looks like this line of code will cause compilation warning.

```
[1677/1717] Building CXX object 
lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVISelLowering.cpp.o
/tmp/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp:315:24: warning: 
braces around scalar initializer [-Wbraced-scalar-init]
setOperationAction({ISD::CTLZ}, XLenVT, Legal);
   ^~~
1 warning generated.
[1717/1717] Creating library symlink lib/libclang-cpp.so
[1542/1716] Building CXX object 
lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVISelLowering.cpp.o
/tmp/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp:315:24: warning: 
braces around scalar initializer [-Wbraced-scalar-init]
setOperationAction({ISD::CTLZ}, XLenVT, Legal);
   ^~~
1 warning generated.
[1716/1716] Linking C executable bin/mlir-capi-execution-engine-test
```



Comment at: llvm/lib/Target/RISCV/RISCVISelLowering.cpp:320
+if (Subtarget.is64Bit())
+  setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_UNDEF}, MVT::i32, Custom);
+  }

And this one


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143439

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2023-01-16 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

On Mon, Jan 16, 2023 Roman Lebedev  wrote:

> Reminder to please always mention the reason for the revert/recommit in the 
> commit message.

Thanks! This change needs to be fixed up (see comments above).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2023-01-12 Thread Yingchi Long 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 rGe327b52766ed: [C2x] reject type definitions in offsetof 
(authored by inclyc).

Changed prior to commit:
  https://reviews.llvm.org/D133574?vs=482719=488877#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/C/drs/dr4xx.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/drs/dr4xx.c
===
--- clang/test/C/drs/dr4xx.c
+++ clang/test/C/drs/dr4xx.c
@@ -352,11 +352,10 @@
  */
 
   /* The DR asked a question about whether defining a new type within offsetof
-   * is allowed. C2x N2350 made this explicitly undefined behavior, but Clang
-   * has always supported defining a type in this location, and GCC also
-   * supports it.
+   * is allowed. C2x N2350 made this explicitly undefined behavior, but GCC
+   * supports it, Clang diagnoses this a UB and rejects it.
*/
-   (void)__builtin_offsetof(struct S { int a; }, a);
+   (void)__builtin_offsetof(struct S { int a; }, a); /* expected-error{{'struct S' cannot be defined in '__builtin_offsetof'}} */
 }
 
 /* WG14 DR499: yes
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+int anonymous_struct() {
+  return __builtin_offsetof(struct // expected-error-re{{'struct (unnamed at {{.*}})' cannot be defined in '__builtin_offsetof'}}
+  { 
+int a;
+int b;
+  }, a);
+}
+
+int struct_in_second_param() {
+  struct A {
+int a, b;
+int x[20];
+  };
+  return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // no-error
+}
+
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'struct A' cannot be defined in 'offsetof'}}
+   // expected-error@-1{{'struct B' cannot be defined in 'offsetof'}}
+  { 
+int a;
+struct B // verifier seems to think the error is emitted by the macro
+ // In fact the location of the error is "B" on the line above
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#undef offsetof
+
+#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
+
+// no warning for 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2023-01-12 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2023-01-01 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-12-13 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

Hi @aaron.ballman seems we are failing on recent change 
2fc5a3410087c209567c7e4a2c457b6896c127a3 


  /* The DR asked a question about whether defining a new type within offsetof
   * is allowed. C2x N2350 made this explicitly undefined behavior, but Clang
   * has always supported defining a type in this location, and GCC also
   * supports it.
   */
   (void)__builtin_offsetof(struct S { int a; }, a);

Do you think this patch should still be merged into mainline? Or do we turn 
this error into a warning?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-12-13 Thread Yingchi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 482719.
inclyc added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+int anonymous_struct() {
+  return __builtin_offsetof(struct // expected-error-re{{'struct (unnamed at {{.*}})' cannot be defined in '__builtin_offsetof'}}
+  { 
+int a;
+int b;
+  }, a);
+}
+
+int struct_in_second_param() {
+  struct A {
+int a, b;
+int x[20];
+  };
+  return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // no-error
+}
+
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'struct A' cannot be defined in 'offsetof'}}
+   // expected-error@-1{{'struct B' cannot be defined in 'offsetof'}}
+  { 
+int a;
+struct B // verifier seems to think the error is emitted by the macro
+ // In fact the location of the error is "B" on the line above
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#undef offsetof
+
+#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
+
+// no warning for traditional offsetof as a function-like macro
+int * macro_func(void) {
+  return offsetof(struct A // no-warning
+  { 
+int a;
+int b;
+  }, a);
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10181,13 +10181,12 @@
 
   bool Owned = false;
   bool IsDependent = false;
-  Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
-KWLoc, SS, Name, NameLoc, Attr, AS_none,
-/*ModulePrivateLoc=*/SourceLocation(),
-MultiTemplateParamsArg(), Owned, IsDependent,
-SourceLocation(), false, TypeResult(),
-/*IsTypeSpecifier*/false,
-/*IsTemplateParamOrArg*/false);
+  Decl *TagD = ActOnTag(
+  S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, AS_none,
+  /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned,
+  IsDependent, SourceLocation(), false, TypeResult(),
+  

[PATCH] D137343: [clang] add -Wvla-stack-allocation

2022-12-07 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137343

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


[PATCH] D132952: [Sema] disable -Wvla for function array parameters

2022-11-24 Thread Yingchi Long via Phabricator via cfe-commits
inclyc abandoned this revision.
inclyc added a comment.

Prefer https://reviews.llvm.org/D137343


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132952

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


[PATCH] D137343: [clang] add -Wvla-stack-allocation

2022-11-22 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

We may need a release note here so users know about the new changes to -Wvla. 
See `clang/docs/ReleaseNotes.rst`!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137343

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


[PATCH] D137839: [Sema] check InitListExpr format strings like {"foo"}

2022-11-22 Thread Yingchi Long 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 rG2ec79afd8993: [Sema] check InitListExpr format strings like 
{foo} (authored by inclyc).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137839

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/format-strings.cpp


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,12 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format 
specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is 
not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 
'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
+
+  constexpr const char *fmt2 {"%d"}; // expected-note{{format string is 
defined here}}
+  printf(fmt2, "oops"); // expected-warning{{format specifies type 'int' but 
the argument has type}}
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8585,6 +8585,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,12 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
+
+  constexpr const char *fmt2 {"%d"}; // expected-note{{format string is defined here}}
+  printf(fmt2, "oops"); // expected-warning{{format specifies type 'int' but the argument has type}}
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8585,6 +8585,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137839: [Sema] check InitListExpr format strings like {"foo"}

2022-11-22 Thread Yingchi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 477279.
inclyc added a comment.

Address comments

- add a test to coverage warnings if appropriate


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137839

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/format-strings.cpp


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,12 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format 
specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is 
not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 
'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
+
+  constexpr const char *fmt2 {"%d"}; // expected-note{{format string is 
defined here}}
+  printf(fmt2, "oops"); // expected-warning{{format specifies type 'int' but 
the argument has type}}
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8585,6 +8585,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,12 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
+
+  constexpr const char *fmt2 {"%d"}; // expected-note{{format string is defined here}}
+  printf(fmt2, "oops"); // expected-warning{{format specifies type 'int' but the argument has type}}
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8585,6 +8585,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137839: [Sema] check InitListExpr format strings like {"foo"}

2022-11-22 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

Do we need release notes here? This patch is just an improvement to 
https://reviews.llvm.org/D130906


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137839

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


[PATCH] D137839: [Sema] check InitListExpr format strings like {"foo"}

2022-11-17 Thread Yingchi Long via Phabricator via cfe-commits
inclyc added a comment.

ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137839

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


[PATCH] D137839: [Sema] check InitListExpr format strings like {"foo"}

2022-11-11 Thread Yingchi Long via Phabricator via cfe-commits
inclyc created this revision.
Herald added a project: All.
inclyc added a reviewer: aaron.ballman.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Adds InitListExpr case in format string checks.

e.g.

  int sprintf(char *__restrict, const char * __restrict, ...);
  
  int foo()
  {
  char data[100];
  constexpr const char* fmt2{"%d"};  // no-warning
  sprintf(data, fmt2, 123);
  }

Fixes: https://github.com/llvm/llvm-project/issues/58900


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137839

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/format-strings.cpp


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,9 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format 
specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is 
not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 
'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8554,6 +8554,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was


Index: clang/test/SemaCXX/format-strings.cpp
===
--- clang/test/SemaCXX/format-strings.cpp
+++ clang/test/SemaCXX/format-strings.cpp
@@ -203,6 +203,9 @@
   printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
   printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is not a string literal}}
   printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
+
+  constexpr const char *fmt {"%d%d"};
+  printf(fmt, 1, 1); // no-warning
 }
 
 
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8554,6 +8554,15 @@
 return SLCT_UncheckedLiteral;
 
   switch (E->getStmtClass()) {
+  case Stmt::InitListExprClass:
+// Handle expressions like {"foobar"}.
+if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
+  return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
+   Type, CallType, /*InFunctionCall*/ false,
+   CheckedVarArgs, UncoveredArg, Offset,
+   IgnoreStringsWithoutSpecifiers);
+}
+return SLCT_NotALiteral;
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::ConditionalOperatorClass: {
 // The expression is a literal if both sub-expressions were, and it was
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137043: [clang] add implicit include for Linux/gnu compatibility

2022-10-30 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> That is OK for glibc system because glibc includes this file manually. But 
> with other libc (e.g. musl), which does not manually include this, clang will 
> fail but GCC can get it compiled.

FWIW currently we cannot build libedit using clang on x86_64-unknown-linux-musl 
and to fix this issue, they have a workaround here 
https://patchwork.ozlabs.org/project/buildroot/patch/1452127277-9538-1-git-send-email-sergio.pr...@e-labworks.com/
 which manually defined `__STDC_ISO_10646__`

Reproducer:

  #include 
  // #include 
  
  int main() {
  printf("%d", __STDC_ISO_10646__);
  }

GCC accepted this code but clang complained `use of undeclared identifier 
'__STDC_ISO_10646__'`

  test.c:5:15: error: use of undeclared identifier '__STDC_ISO_10646__'
  printf("%d", __STDC_ISO_10646__);
   ^
  1 error generated.

Note that glibc includes `stdc-predefs.h` at the source-code level, so this 
problem cannot be reproduced on the glibc-based systems. (The header `stdio.h` 
actually #includes `stdc-predefs.h` in glibc!)

However if we do not #include `stdio.h`, different behaviors can be seen on 
glibc platforms.

  int main() {
return __STDC_ISO_10646__;
  }

See https://godbolt.org/z/Gd9Kbn766.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137043

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


[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-10-18 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D133248#3865010 , @SuibianP wrote:

> @aaron.ballman Thanks for the guidance! I have rectified the parentheses and 
> appended to the release notes. Please feel free to point out any additional 
> issues with the Differential.
>
> If all is good, I would like to have the patch attributed to `Jialun Hu 
> `.

Thanks @SuibianP ! I've committed this for you.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133248

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


[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-10-18 Thread YingChi Long 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 rG94e8bd002c81: [clang] Fix crash upon stray coloncolon token 
in C2x mode (authored by Jialun Hu jialun...@apple.com, committed by 
inclyc).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133248

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/Parser.cpp
  clang/test/Parser/c2x-attributes.c


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot 
appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as 
scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope 
either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5411,6 +5411,8 @@
 return isDeclarationSpecifier(AllowImplicitTypename);
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new
 NextToken().is(tok::kw_delete))   // ::delete
   return false;
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -866,10 +866,11 @@
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
   bool MightBeCXXScopeToken() {
-return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
-   (Tok.is(tok::annot_template_id) &&
-NextToken().is(tok::coloncolon)) ||
-   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+return getLangOpts().CPlusPlus &&
+   (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+(Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
   }
   bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
 return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -251,6 +251,7 @@
 - Address the thread identification problems in coroutines.
   `Issue 47177 `_
   `Issue 47179 `_
+- Fix a crash upon stray coloncolon token in C2x mode.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;

[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-11 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

This makes sense! However I think `assert(0)` should not be used in this case, 
we could expose another `llvm_unreachable`-like api and probably 
`llvm_report_error` shall be fine. Are there some changed assertions actually 
"Aspirationally unreachable" in this patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

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


[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-11 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D135551#3849983 , @aaron.ballman 
wrote:

> In D135551#3849944 , @inclyc wrote:
>
>>> - Prefer llvm_report_error() in any circumstance under which a code path is 
>>> functionally possible to reach, but only in erroneous executions that 
>>> signify a mistake on the part of the LLVM developer elsewhere in the 
>>> program.
>>> - Prefer llvm_unreachable() in any circumstance under which a code path is 
>>> believed to be functionally impossible to reach (even if technically 
>>> possible to reach). The API is now self-documenting to mean "this code 
>>> really should be totally unreachable".
>>
>> I think `llvm_unreachable` already has the functionality reporting bugs for 
>> developer in our implementation, with +Assertions by default
>
> Yes, in terms of its runtime behavior. So long as we're not making debugging 
> harder for some large group of people, the runtime behavior is not really 
> what I'm concerned by though. I'm focusing more on code reviewers and project 
> newcomers and whether our code is self-documenting or not. Having a policy to 
> use an API that says code is not reachable in situations where that code is 
> very much reachable is the crux of my problem -- the API is sometimes a lie 
> (and a lie with optimization impacts, at that) and we force everyone to pay 
> the cognitive costs associated with that when reading code.
>
> If we end up with two APIs that have the same runtime behavior, I'm okay with 
> that.

Could you elaborate on "aspirationally" vs "functionally" unreachable code here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

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


[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-11 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> - Prefer llvm_report_error() in any circumstance under which a code path is 
> functionally possible to reach, but only in erroneous executions that signify 
> a mistake on the part of the LLVM developer elsewhere in the program.
> - Prefer llvm_unreachable() in any circumstance under which a code path is 
> believed to be functionally impossible to reach (even if technically possible 
> to reach). The API is now self-documenting to mean "this code really should 
> be totally unreachable".

I think `llvm_unreachable` already has the functionality reporting bugs for 
developer in our implementation, with +Assertions by default


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

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


[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-10 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> I've left some comments in the review about examples of my concerns (it's not 
> an exhaustive review).

Thanks @aaron.ballman ! I didn't quite understand the original meaning of this 
code here (e.g. libclang), and I have now removed the relevant changes. I think 
this patch should replace the code that accidentally misuses of `assert(0)` 
with `llvm_unreachable()`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

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


[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-10 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 466539.
inclyc added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

Files:
  clang/include/clang/AST/Redeclarable.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/Analysis/CFG.cpp
  clang/lib/Basic/SourceManager.cpp
  clang/lib/Basic/Targets/NVPTX.cpp
  clang/lib/CodeGen/CGHLSLRuntime.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/Multilib.cpp
  clang/lib/Driver/ToolChains/Flang.cpp
  clang/lib/Format/Format.cpp
  clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
  clang/lib/Frontend/Rewrite/RewriteObjC.cpp
  clang/lib/Frontend/SARIFDiagnostic.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PreprocessingRecord.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
  clang/lib/StaticAnalyzer/Core/SVals.cpp
  clang/tools/clang-refactor/TestSupport.cpp

Index: clang/tools/clang-refactor/TestSupport.cpp
===
--- clang/tools/clang-refactor/TestSupport.cpp
+++ clang/tools/clang-refactor/TestSupport.cpp
@@ -348,7 +348,7 @@
 if (!Matches[2].empty()) {
   // Don't forget to drop the '+'!
   if (Matches[2].drop_front().getAsInteger(10, ColumnOffset))
-assert(false && "regex should have produced a number");
+llvm_unreachable("regex should have produced a number");
 }
 Offset = addColumnOffset(Source, Offset, ColumnOffset);
 unsigned EndOffset;
@@ -365,7 +365,7 @@
   unsigned EndLineOffset = 0, EndColumn = 0;
   if (EndLocMatches[1].drop_front().getAsInteger(10, EndLineOffset) ||
   EndLocMatches[2].getAsInteger(10, EndColumn))
-assert(false && "regex should have produced a number");
+llvm_unreachable("regex should have produced a number");
   EndOffset = addEndLineOffsetAndEndColumn(Source, Offset, EndLineOffset,
EndColumn);
 } else {
Index: clang/lib/StaticAnalyzer/Core/SVals.cpp
===
--- clang/lib/StaticAnalyzer/Core/SVals.cpp
+++ clang/lib/StaticAnalyzer/Core/SVals.cpp
@@ -355,7 +355,7 @@
   break;
 }
 default:
-  assert(false && "Pretty-printed not implemented for this NonLoc.");
+  llvm_unreachable("Pretty-printed not implemented for this NonLoc.");
   break;
   }
 }
Index: clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
===
--- clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -192,7 +192,7 @@
   break;
 
 case ProgramPoint::BlockExitKind:
-  assert(false && "BlockExit location never occur in forward analysis.");
+  llvm_unreachable("BlockExit location never occur in forward analysis.");
   break;
 
 case ProgramPoint::CallEnterKind:
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -2438,7 +2438,7 @@
 MacroID ID = MacroInfosToEmit[I].ID;
 
 if (ID < FirstMacroID) {
-  assert(0 && "Loaded MacroInfo entered MacroInfosToEmit ?");
+  llvm_unreachable("Loaded MacroInfo entered MacroInfosToEmit ?");
   continue;
 }
 
@@ -5381,7 +5381,8 @@
 TypeIdx  = TypeIdxs[T];
 if (Idx.getIndex() == 0) {
   if (DoneWritingDeclsAndTypes) {
-assert(0 && "New type seen after serializing all the types to emit!");
+llvm_unreachable(
+"New type seen after serializing all the types to emit!");
 return TypeIdx();
   }
 
@@ -5427,7 +5428,8 @@
   DeclID  = DeclIDs[D];
   if (ID == 0) {
 if (DoneWritingDeclsAndTypes) {
-  assert(0 && "New decl seen after serializing all the decls to emit!");
+  llvm_unreachable(
+  "New decl seen after serializing all the decls to emit!");
   return 0;
 }
 
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -7464,7 +7464,7 @@
   unsigned Index = ID - NUM_PREDEF_DECL_IDS;
 
   if (Index >= DeclsLoaded.size()) {
-assert(0 && "declaration ID out-of-range for AST file");
+llvm_unreachable("declaration ID out-of-range for AST file");
 Error("declaration ID out-of-range for AST file");
 return nullptr;
   }
@@ -7479,7 +7479,7 @@
   unsigned Index = ID - NUM_PREDEF_DECL_IDS;
 
   if (Index >= 

[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-10 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D135551#3846592 , @aaron.ballman 
wrote:

> I don't know if that discussion reached a conclusion to move forward with 
> this change -- my reading of the conversation was that efforts would be 
> better spend on fuzzing instead of changing policy about using unreachable vs 
> assert(0).
>
> In general, I'm a bit hesitant to make this change. On the one hand, it's 
> logically no worse than using `assert(0)` in a release build (if you hit this 
> code path, bad things are going to happen). But `__builtin_unreachable` can 
> have time travel optimization effects that `assert` doesn't have, and so the 
> kind of bad things which can happen are different between the two (and use of 
> unreachable on reachable code paths might make for harder debugging in 
> RelWithDebInfo builds). Historically, we've usually used `llvm_unreachable` 
> for situations where we're saying "this code cannot be reached; if it can, 
> something else has gone seriously wrong." For example, in code like: `int 
> foo(SomeEnum E) { switch (E) { case One: return 1; default: return 2; } 
> llvm_unreachable("getting here would be mysterious"); }` and we've used 
> `assert(0)` for situations where we're saying "this code is possible to reach 
> only when there were mistakes elsewhere which broke invariants we were 
> relying on." The two situations are similar, but still different enough that 
> I don't think we should wholesale change from one form to another.



> but still different enough that I don't think we should wholesale change from 
> one form to another.

In general we can control the behavior here via `-DLLVM_UNREACHABLE_OPTIMIZE` 
to choose making assumptions or traps (looks better than assertions to me).

https://github.com/llvm/llvm-project/blob/50312ea133999cb2aad1ab9ef0ec39429a9427c5/llvm/include/llvm/Support/ErrorHandling.h#L125

(This change was landed 7 months ago https://reviews.llvm.org/D121750)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

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


[PATCH] D135551: [clang] replace `assert(0)` with `llvm_unreachable` NFC

2022-10-10 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 466471.
inclyc added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fix CI issue


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135551

Files:
  clang/include/clang/AST/Redeclarable.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/Analysis/CFG.cpp
  clang/lib/Basic/SourceManager.cpp
  clang/lib/Basic/Targets/NVPTX.cpp
  clang/lib/CodeGen/CGHLSLRuntime.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/Multilib.cpp
  clang/lib/Driver/ToolChains/Flang.cpp
  clang/lib/Format/Format.cpp
  clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
  clang/lib/Frontend/Rewrite/RewriteObjC.cpp
  clang/lib/Frontend/SARIFDiagnostic.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PreprocessingRecord.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
  clang/lib/StaticAnalyzer/Core/SVals.cpp
  clang/tools/clang-refactor/TestSupport.cpp
  clang/tools/libclang/CIndex.cpp
  clang/tools/libclang/CXCursor.cpp
  clang/utils/TableGen/ClangSyntaxEmitter.cpp

Index: clang/utils/TableGen/ClangSyntaxEmitter.cpp
===
--- clang/utils/TableGen/ClangSyntaxEmitter.cpp
+++ clang/utils/TableGen/ClangSyntaxEmitter.cpp
@@ -117,7 +117,7 @@
 } else if (R.isSubClassOf("NodeType")) {
   NodeType = R.getName().str();
 } else {
-  assert(false && "Unhandled Syntax kind");
+  llvm_unreachable("Unhandled Syntax kind");
 }
   }
 
Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -1487,12 +1487,12 @@
   TemplateArgument TA;
   if (clang_Cursor_getTemplateArgument(C, I, ) !=
   CXGetTemplateArgumentStatus_Success) {
-assert(0 && "Unable to retrieve TemplateArgument");
+llvm_unreachable("Unable to retrieve TemplateArgument");
 return 0;
   }
 
   if (TA.getKind() != TemplateArgument::Integral) {
-assert(0 && "Passed template argument is not Integral");
+llvm_unreachable("Passed template argument is not Integral");
 return 0;
   }
 
@@ -1504,12 +1504,12 @@
   TemplateArgument TA;
   if (clang_Cursor_getTemplateArgument(C, I, ) !=
   CXGetTemplateArgumentStatus_Success) {
-assert(0 && "Unable to retrieve TemplateArgument");
+llvm_unreachable("Unable to retrieve TemplateArgument");
 return 0;
   }
 
   if (TA.getKind() != TemplateArgument::Integral) {
-assert(0 && "Passed template argument is not Integral");
+llvm_unreachable("Passed template argument is not Integral");
 return 0;
   }
 
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -199,7 +199,7 @@
   if (clang_isDeclaration(Cursor.kind)) {
 const Decl *D = getCursorDecl(Cursor);
 if (!D) {
-  assert(0 && "Invalid declaration cursor");
+  llvm_unreachable("Invalid declaration cursor");
   return true; // abort.
 }
 
@@ -5188,7 +5188,7 @@
 return P->FullyQualifiedName;
   }
 
-  assert(false && "Invalid CXPrintingPolicyProperty");
+  llvm_unreachable("Invalid CXPrintingPolicyProperty");
   return 0;
 }
 
@@ -5280,7 +5280,7 @@
 return;
   }
 
-  assert(false && "Invalid CXPrintingPolicyProperty");
+  llvm_unreachable("Invalid CXPrintingPolicyProperty");
 }
 
 CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
Index: clang/tools/clang-refactor/TestSupport.cpp
===
--- clang/tools/clang-refactor/TestSupport.cpp
+++ clang/tools/clang-refactor/TestSupport.cpp
@@ -348,7 +348,7 @@
 if (!Matches[2].empty()) {
   // Don't forget to drop the '+'!
   if (Matches[2].drop_front().getAsInteger(10, ColumnOffset))
-assert(false && "regex should have produced a number");
+llvm_unreachable("regex should have produced a number");
 }
 Offset = addColumnOffset(Source, Offset, ColumnOffset);
 unsigned EndOffset;
@@ -365,7 +365,7 @@
   unsigned EndLineOffset = 0, EndColumn = 0;
   if (EndLocMatches[1].drop_front().getAsInteger(10, EndLineOffset) ||
   EndLocMatches[2].getAsInteger(10, EndColumn))
-assert(false && "regex should have produced a number");
+llvm_unreachable("regex should have produced a number");
   EndOffset = addEndLineOffsetAndEndColumn(Source, Offset, EndLineOffset,

[PATCH] D134815: [Sema] print more readable identifier of anonymous struct of -Wconsumed

2022-09-28 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Working in D133574  we discovered -Wconsumed 
print '' with anonymous
class/struct. After this patch we give a line number, file name of
anonymous struct/class declaration.

Example:

  struct S {
struct {
  __attribute__((callable_when(consumed))) void func();
} s;
  };



  local/anoy-consume.cpp:3:20: warning: consumed analysis attribute is attached 
to member of class 'S::(unnamed struct at local/anoy-consume.cpp:2:3)' which 
isn't marked as consumable [-Wconsumed]
  __attribute__((callable_when(consumed))) void func();
 ^
  1 warning generated.

Link: https://reviews.llvm.org/D133574#3817743
Link: https://godbolt.org/z/16vP3voTW


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134815

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaCXX/warn-consumed-parsing.cpp


Index: clang/test/SemaCXX/warn-consumed-parsing.cpp
===
--- clang/test/SemaCXX/warn-consumed-parsing.cpp
+++ clang/test/SemaCXX/warn-consumed-parsing.cpp
@@ -62,5 +62,10 @@
   Status {
 };
 
-
-
+class Anonymous {
+  struct /* anonymous */ {
+void callableWhen()   CALLABLE_WHEN("unconsumed"); // expected-warning-re 
{{consumed analysis attribute is attached to member of class 
'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+void consumes()   SET_TYPESTATE(consumed); // expected-warning-re 
{{consumed analysis attribute is attached to member of class 
'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+bool testUnconsumed() TEST_TYPESTATE(consumed); // expected-warning-re 
{{consumed analysis attribute is attached to member of class 
'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+  } anonymous;
+};
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1223,7 +1223,8 @@
 
   if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
 if (!RD->hasAttr()) {
-  S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
+  S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class)
+  << S.Context.getTagDeclType(RD);
 
   return false;
 }
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -212,6 +212,8 @@
   of FAM-like arrays.
 - Clang now correctly diagnoses a warning when defercencing a void pointer in 
C mode.
   This fixes `Issue 53631 `_
+- Clang now prints more readable identifier for anonymous class/struct of
+  ``-Wconsumed``.
 
 Non-comprehensive list of changes in this release
 -


Index: clang/test/SemaCXX/warn-consumed-parsing.cpp
===
--- clang/test/SemaCXX/warn-consumed-parsing.cpp
+++ clang/test/SemaCXX/warn-consumed-parsing.cpp
@@ -62,5 +62,10 @@
   Status {
 };
 
-
-
+class Anonymous {
+  struct /* anonymous */ {
+void callableWhen()   CALLABLE_WHEN("unconsumed"); // expected-warning-re {{consumed analysis attribute is attached to member of class 'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+void consumes()   SET_TYPESTATE(consumed); // expected-warning-re {{consumed analysis attribute is attached to member of class 'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+bool testUnconsumed() TEST_TYPESTATE(consumed); // expected-warning-re {{consumed analysis attribute is attached to member of class 'Anonymous::(unnamed struct at {{.*}})' which isn't marked as consumable}}
+  } anonymous;
+};
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -1223,7 +1223,8 @@
 
   if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
 if (!RD->hasAttr()) {
-  S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
+  S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class)
+  << S.Context.getTagDeclType(RD);
 
   return false;
 }
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -212,6 +212,8 @@
   of FAM-like arrays.
 - Clang now correctly diagnoses a warning when defercencing a void pointer in C mode.
   This fixes `Issue 53631 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 463063.
inclyc added a comment.

This revision fixes:

**anonymous struct**

> You should be able to pass in the TagDecl directly because the diagnostics
> engine knows how to print a NamedDecl.

I've switch back to using `Context.getTagDeclType(New)` because this can print
anonymous pretty.

  clang/test/C/C2x/n2350.c:23:29: error: 'struct (unnamed at 
clang/test/C/C2x/n2350.c:23:29)' cannot be defined in '__builtin_offsetof'
return __builtin_offsetof(struct // expected-error-re{{'struct (unnamed at 
{{.*}})' cannot be defined in '__builtin_offsetof'}}

**definitions within the second parameter**

I've add a new test case for this. This bug is caused by the RAIIObject having
incorrect scope.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+int anonymous_struct() {
+  return __builtin_offsetof(struct // expected-error-re{{'struct (unnamed at {{.*}})' cannot be defined in '__builtin_offsetof'}}
+  { 
+int a;
+int b;
+  }, a);
+}
+
+int struct_in_second_param() {
+  struct A {
+int a, b;
+int x[20];
+  };
+  return __builtin_offsetof(struct A, x[sizeof(struct B{int a;})]); // no-error
+}
+
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'struct A' cannot be defined in 'offsetof'}}
+   // expected-error@-1{{'struct B' cannot be defined in 'offsetof'}}
+  { 
+int a;
+struct B // verifier seems to think the error is emitted by the macro
+ // In fact the location of the error is "B" on the line above
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#undef offsetof
+
+#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
+
+// no warning for traditional offsetof as a function-like macro
+int * macro_func(void) {
+  return offsetof(struct A // no-warning
+  { 
+int a;
+int b;
+  }, a);
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10053,13 +10053,12 @@
 
   bool Owned = false;
   bool IsDependent = false;
-  Decl *TagD = 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 462942.
inclyc added a comment.

Fix comment nits


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'A' cannot be defined in 'offsetof'}}
+   // expected-error@-1{{'B' cannot be defined in 'offsetof'}}
+  { 
+int a;
+struct B // verifier seems to think the error is emitted by the macro
+ // In fact the location of the error is "B" on the line above
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#undef offsetof
+
+#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
+
+// no warning for traditional offsetof as a function-like macro
+int * macro_func(void) {
+  return offsetof(struct A // no-warning
+  { 
+int a;
+int b;
+  }, a);
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10053,13 +10053,12 @@
 
   bool Owned = false;
   bool IsDependent = false;
-  Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
-KWLoc, SS, Name, NameLoc, Attr, AS_none,
-/*ModulePrivateLoc=*/SourceLocation(),
-MultiTemplateParamsArg(), Owned, IsDependent,
-SourceLocation(), false, TypeResult(),
-/*IsTypeSpecifier*/false,
-/*IsTemplateParamOrArg*/false);
+  Decl *TagD = ActOnTag(
+  S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, AS_none,
+  /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned,
+  IsDependent, SourceLocation(), false, TypeResult(),
+  /*IsTypeSpecifier*/ false,
+  /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside);
   assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
 
   if (!TagD)
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -16922,15 +16922,15 @@
   

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 462940.
inclyc added a comment.

Address comments from @aaron.ballman

Move `OffsetOfKind` to `Sema` and pass it to `Sema:ActOnTag` directly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'A' cannot be defined in 'offsetof'}}
+   // expected-error@-1{{'B' cannot be defined in 'offsetof'}}
+  { 
+int a;
+struct B // verifier seems to think the error is emitted by the macro
+ // In fact the location of the error is "B" on the line above
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#undef offsetof
+
+#define offsetof(TYPE, MEMBER) (&((TYPE *)0)->MEMBER)
+
+// no warning for traditional offsetof as a function-like macro
+int * macro_func(void) {
+  return offsetof(struct A // no-warning
+  { 
+int a;
+int b;
+  }, a);
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10053,13 +10053,12 @@
 
   bool Owned = false;
   bool IsDependent = false;
-  Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
-KWLoc, SS, Name, NameLoc, Attr, AS_none,
-/*ModulePrivateLoc=*/SourceLocation(),
-MultiTemplateParamsArg(), Owned, IsDependent,
-SourceLocation(), false, TypeResult(),
-/*IsTypeSpecifier*/false,
-/*IsTemplateParamOrArg*/false);
+  Decl *TagD = ActOnTag(
+  S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr, AS_none,
+  /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned,
+  IsDependent, SourceLocation(), false, TypeResult(),
+  /*IsTypeSpecifier*/ false,
+  /*IsOffsetOfInMacro=*/false, /*OOK=*/OOK_Outside);
   assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
 
   if (!TagD)
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

related kernel patch https://lkml.org/lkml/2022/9/26/1484


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:3279
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
+ bool IsWithinOffsetOf, bool IsOffsetOfInMacro,
  SkipBodyInfo *SkipBody = nullptr);

aaron.ballman wrote:
> Instead of passing two `bool`s, why not pass `Parser::OffsetOfStateKind` 
> directly?
`Parser::OffsetOfStateKind` is not visible to class `Sema`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

Hi @aaron.ballman, I've noticed in the linux kernel, type alignment was 
implemented by a tricky way using offsetof.

  #define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)

Does this always has the same semantic with C11 `_Alignof`? If this is not 
true, I think unfortunately we may emit a switchable warning instead of an 
error to preserve semantics here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 462680.
inclyc added a comment.

Address comments.

Clang will now consider __builtin_offsetof #defined from "offsetof" to improve
diagnostic message.

For example:

  #define offsetof(t, d) __builtin_offsetof(t, d)
  
  int main() {
return offsetof(struct S { int a; }, a);
  }



  local/offsetof.c:4:26: error: 'S' cannot be defined in 'offsetof'
return offsetof(struct S { int a; }, a);
   ^
  1 error generated.

Emm, the "expected-error" of struct B within a macro seems have to be annotated
at the same line as"struct A".

  int macro(void) {
return offsetof(struct A // expected-error{{'A' cannot be defined in 
'offsetof'}}
 // expected-error@-1{{'B' cannot be defined in 
'offsetof'}} < Have to write this here, but I believe the line number 
is correct
{ 
  int a;
  struct B // FIXME: verifier seems to think the error is emitted by the 
macro
   // In fact the location of the error is "B" on the line above
  {
int c;
int d;
  } x;
}, a);
  }



  clang/test/C/C2x/n2350.c:11:36: error: 'A' cannot be defined in 
'__builtin_offsetof'
return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined 
in '__builtin_offsetof'}} 
 ^
  clang/test/C/C2x/n2350.c:14:12: error: 'B' cannot be defined in 
'__builtin_offsetof'
  struct B // expected-error{{'B' cannot be defined in 
'__builtin_offsetof'}} 
 ^
  clang/test/C/C2x/n2350.c:26:26: error: 'A' cannot be defined in 'offsetof'
return offsetof(struct A // expected-error{{'A' cannot be defined in 
'offsetof'}}
   ^
  clang/test/C/C2x/n2350.c:30:12: error: 'B' cannot be defined in 'offsetof' 
<-- note that this line number is "30" (not "26")
  struct B // FIXME: verifier seems to think the error is emitted by the 
macro
 ^
  4 errors generated.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/C/C2x/n2350.c
  clang/test/Parser/declarators.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,20 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // FIXME: error diagnostic message for nested definitions 
+ // https://reviews.llvm.org/D133574 
+ // fixme-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/test/C/C2x/n2350.c
===
--- /dev/null
+++ clang/test/C/C2x/n2350.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c89 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c99 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -verify %s
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int simple(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'B' cannot be defined in '__builtin_offsetof'}} 
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
+
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+
+int macro(void) {
+  return offsetof(struct A // expected-error{{'A' cannot be defined in 'offsetof'}}
+

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-23 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:1650
+def err_type_defined_in_offsetof : Error<
+  "%0 cannot be defined in '__builtin_offsetof'">;
 

aaron.ballman wrote:
> inclyc wrote:
> > aaron.ballman wrote:
> > > We might want this change, we might not -- can you test the diagnostic 
> > > behavior when using `#include `? Does it print 
> > > `__builtin_offsetof` in the following example?
> > > ```
> > > #include 
> > > 
> > > int main() {
> > >   return offsetof(struct S { int a; }, a);
> > > }
> > > ```
> > > when executed with `clang -fsyntax-only -ffreestanding -std=c2x test.c`
> > > 
> > > If it prints the builtin name, I think we'll want to look at the builtin 
> > > token to see if it was expanded from a macro named `offsetof` to improve 
> > > the diagnostic quality.
> > ```
> > local/offsetofcc.c:4:26: error: 'struct S' cannot be defined in 
> > '__builtin_offsetof'
> >   return offsetof(struct S { int a; }, a);
> >  ^
> > 1 error generated.
> > ```
> > > If it prints the builtin name, I think we'll want to look at the builtin 
> > > token to see if it was expanded from a macro named offsetof to improve 
> > > the diagnostic quality.
> > 
> > OK
> We have similar code for this here: 
> 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaChecking.cpp#L13438
> We have similar code for this here:

Wow! Thank you so much for this. I'm searching for how to do this in a LOT of 
doxygen generated pages (


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-23 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

Emm, is it necessary to add a `LangOpts` check so that this change only applies 
to c2x? If clang was invoked without `-std=c2x`, should we just accept 
`offsetof` with definitions?




Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:1650
+def err_type_defined_in_offsetof : Error<
+  "%0 cannot be defined in '__builtin_offsetof'">;
 

aaron.ballman wrote:
> We might want this change, we might not -- can you test the diagnostic 
> behavior when using `#include `? Does it print `__builtin_offsetof` 
> in the following example?
> ```
> #include 
> 
> int main() {
>   return offsetof(struct S { int a; }, a);
> }
> ```
> when executed with `clang -fsyntax-only -ffreestanding -std=c2x test.c`
> 
> If it prints the builtin name, I think we'll want to look at the builtin 
> token to see if it was expanded from a macro named `offsetof` to improve the 
> diagnostic quality.
```
local/offsetofcc.c:4:26: error: 'struct S' cannot be defined in 
'__builtin_offsetof'
  return offsetof(struct S { int a; }, a);
 ^
1 error generated.
```
> If it prints the builtin name, I think we'll want to look at the builtin 
> token to see if it was expanded from a macro named offsetof to improve the 
> diagnostic quality.

OK


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-21 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 461822.
inclyc added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,18 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16256,7 +16256,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17029,10 +17029,16 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinOffsetOf && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
-  if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
-  TUK == TUK_Definition) {
+  if (!Invalid && getLangOpts().CPlusPlus &&
+  (IsTypeSpecifier || IsTemplateParamOrArg) && TUK == TUK_Definition) {
 Diag(New->getLocation(), diag::err_type_defined_in_type_specifier)
   << Context.getTagDeclType(New);
 Invalid = true;
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,6 +2579,7 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
+InBuiltInOffsetOfBaseRAIIObject InOffsetof(*this, true);
 TypeResult Ty = ParseTypeName();
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC == DeclSpecContext::DSC_type_specifier,
 DSC == DeclSpecContext::DSC_template_param ||
 DSC == DeclSpecContext::DSC_template_type_arg,
-);
+, InBuiltInOffsetOfBase);
 
 // If ActOnTag said the type was dependent, try again with the
 // less common call.
Index: clang/include/clang/Sema/Sema.h
===
--- 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-19 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 461463.
inclyc added a comment.

Switch back to RAIIObject.

Currently clang could not generate diagnostic messages for nested definitions
in C++. I believe using RAIIObject here is logically correct, but in C++ mode,
`ActOnTag` returns `nullptr`, and the comment says

> We can't recover well from the cases where we make the type anonymous



  /* SemaDecl.cpp Sema::ActOnTag Ln 17189 */
  // In C++, don't return an invalid declaration. We can't recover well from
  // the cases where we make the type anonymous.
  if (Invalid && getLangOpts().CPlusPlus) {
if (New->isBeingDefined())
  if (auto RD = dyn_cast(New))
RD->completeDefinition();
return nullptr;
  } else if (SkipBody && SkipBody->ShouldSkip) {
return SkipBody->Previous;
  } else {
return New;
  }

I believe the state "ParsingBuiltinOffsetof" is correctly passed into
`ParseCXXMemberSpecification` (parsing nested definition), and if clang
recovers invalid declaration in the furture, nested definitions will be caught.

  if (TUK == Sema::TUK_Definition) {
assert(Tok.is(tok::l_brace) ||
   (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
   isClassCompatibleKeyword());
if (SkipBody.ShouldSkip)
  SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
 TagOrTempResult.get());
else if (getLangOpts().CPlusPlus)
  ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
  TagOrTempResult.get());  // <  nullptr, 
nested declaration skipped
else {
  Decl *D =
  SkipBody.CheckSameAsPrevious ? SkipBody.New : TagOrTempResult.get();
  // Parse the definition body.
  ParseStructUnionBody(StartLoc, TagType, cast(D));
  if (SkipBody.CheckSameAsPrevious &&
  !Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
DS.SetTypeSpecError();
return;
  }
}
  }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c
  clang/test/SemaCXX/offsetof.cpp

Index: clang/test/SemaCXX/offsetof.cpp
===
--- clang/test/SemaCXX/offsetof.cpp
+++ clang/test/SemaCXX/offsetof.cpp
@@ -83,3 +83,18 @@
   expected-error {{invalid application of 'offsetof' to a field of a virtual base}}
 };
 }
+
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B
+{
+  int c;
+  int d;
+};
+B x;
+  }, a);
+}
Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/Sema/offsetof.c:79
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof 
directly
+{

aaron.ballman wrote:
> inclyc wrote:
> > inclyc wrote:
> > > aaron.ballman wrote:
> > > > inclyc wrote:
> > > > > aaron.ballman wrote:
> > > > > > I think this is defensible. The wording in the standard is "If the 
> > > > > > specified type defines a new type or if the specified member is a 
> > > > > > bit-field, the behavior is undefined." and the specified type in 
> > > > > > this case is `struct A`; that `struct A` happens to also define 
> > > > > > `struct B` is immaterial.
> > > > > > 
> > > > > > However, the intent behind the change to the rule is to support 
> > > > > > older implementations of `offsetof` to protect them from having to 
> > > > > > deal with a case like: `offsetof(struct S { int a, b }, b);` where 
> > > > > > `offsetof` is a macro and thus the comma between `a` and `b` is 
> > > > > > treated as a separator. So there's a part of me that wonders if we 
> > > > > > want to also support diagnosing this case. But then we'd have to 
> > > > > > look at the declarator context more recursively to see whether any 
> > > > > > of the contexts on the stack are an `offsetof` context and that 
> > > > > > might be tricky.
> > > > > > 
> > > > > > Thoughts?
> > > > > FWIW, gcc seems just rejects all definitions in this context. 
> > > > > (Perhaps during Parsing the statements). If we add a bool state to 
> > > > > the Parser (just using RAII object as before) struct B will trigger 
> > > > > diagnostic error because the state "ParsingOffsetof" is passed into 
> > > > > inner declaration.
> > > > GCC accepts currently: https://godbolt.org/z/oEvzjW6Ee but you're 
> > > > correct regarding switching back to an RAII object being an easier way 
> > > > to address the nested declarations.
> > > > 
> > > > Let me think on this situation a bit
> > > > GCC accepts currently
> > > 
> > > C++: https://godbolt.org/z/fon8e7dzf 
> > ```
> > : In function 'int main()':
> > :3:3: error: types may not be defined within '__builtin_offsetof'
> > 3 |   {
> >   |   ^
> > :6:5: error: types may not be defined within '__builtin_offsetof'
> > 6 | {
> >   | ^
> > Compiler returned: 1
> > ```
> C++ is a different language in this case though. In C, you can generally 
> define types anywhere you can spell a type, and in C++ you cannot. e.g., 
> `void func(struct S { int x, y; } s);` is valid in C and invalid in C++.
GCC explicitly reject type definitions since GCC 8 (in C++ mode). I guess the 
logic here in GCC may also add a boolean state parameter to parser.

Interestingly, in C++ we treat the first parameter of `__builtin_offsetof` as a 
type specifier, rejecting the definition of `struct A`, but not rejecting 
nested definition `struct B`

https://godbolt.org/z/PqWjzqqYn

Emm, so, how about switch back to RAIIObject to support diagnosing nested 
definitions?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/Sema/offsetof.c:79
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof 
directly
+{

inclyc wrote:
> aaron.ballman wrote:
> > inclyc wrote:
> > > aaron.ballman wrote:
> > > > I think this is defensible. The wording in the standard is "If the 
> > > > specified type defines a new type or if the specified member is a 
> > > > bit-field, the behavior is undefined." and the specified type in this 
> > > > case is `struct A`; that `struct A` happens to also define `struct B` 
> > > > is immaterial.
> > > > 
> > > > However, the intent behind the change to the rule is to support older 
> > > > implementations of `offsetof` to protect them from having to deal with 
> > > > a case like: `offsetof(struct S { int a, b }, b);` where `offsetof` is 
> > > > a macro and thus the comma between `a` and `b` is treated as a 
> > > > separator. So there's a part of me that wonders if we want to also 
> > > > support diagnosing this case. But then we'd have to look at the 
> > > > declarator context more recursively to see whether any of the contexts 
> > > > on the stack are an `offsetof` context and that might be tricky.
> > > > 
> > > > Thoughts?
> > > FWIW, gcc seems just rejects all definitions in this context. (Perhaps 
> > > during Parsing the statements). If we add a bool state to the Parser 
> > > (just using RAII object as before) struct B will trigger diagnostic error 
> > > because the state "ParsingOffsetof" is passed into inner declaration.
> > GCC accepts currently: https://godbolt.org/z/oEvzjW6Ee but you're correct 
> > regarding switching back to an RAII object being an easier way to address 
> > the nested declarations.
> > 
> > Let me think on this situation a bit
> > GCC accepts currently
> 
> C++: https://godbolt.org/z/fon8e7dzf 
```
: In function 'int main()':
:3:3: error: types may not be defined within '__builtin_offsetof'
3 |   {
  |   ^
:6:5: error: types may not be defined within '__builtin_offsetof'
6 | {
  | ^
Compiler returned: 1
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/Sema/offsetof.c:79
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof 
directly
+{

aaron.ballman wrote:
> inclyc wrote:
> > aaron.ballman wrote:
> > > I think this is defensible. The wording in the standard is "If the 
> > > specified type defines a new type or if the specified member is a 
> > > bit-field, the behavior is undefined." and the specified type in this 
> > > case is `struct A`; that `struct A` happens to also define `struct B` is 
> > > immaterial.
> > > 
> > > However, the intent behind the change to the rule is to support older 
> > > implementations of `offsetof` to protect them from having to deal with a 
> > > case like: `offsetof(struct S { int a, b }, b);` where `offsetof` is a 
> > > macro and thus the comma between `a` and `b` is treated as a separator. 
> > > So there's a part of me that wonders if we want to also support 
> > > diagnosing this case. But then we'd have to look at the declarator 
> > > context more recursively to see whether any of the contexts on the stack 
> > > are an `offsetof` context and that might be tricky.
> > > 
> > > Thoughts?
> > FWIW, gcc seems just rejects all definitions in this context. (Perhaps 
> > during Parsing the statements). If we add a bool state to the Parser (just 
> > using RAII object as before) struct B will trigger diagnostic error because 
> > the state "ParsingOffsetof" is passed into inner declaration.
> GCC accepts currently: https://godbolt.org/z/oEvzjW6Ee but you're correct 
> regarding switching back to an RAII object being an easier way to address the 
> nested declarations.
> 
> Let me think on this situation a bit
> GCC accepts currently

C++: https://godbolt.org/z/fon8e7dzf 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/include/clang/Parse/Parser.h:2311
 case DeclSpecContext::DSC_association:
+case DeclSpecContext::DSC_offsetof:
   return true;

aaron.ballman wrote:
> Is this correct? I don't think we can deduce the type from `offsetof` through 
> CTAD, can we?
> 
> https://godbolt.org/z/Kab6ahYe7
> 
> (This might be a good test case to add assuming we don't already have that 
> coverage.)
Emm, these checks just return as the same as "type_specifier". Because that's 
what we passed into "ParsingTypename" before.



Comment at: clang/test/Sema/offsetof.c:79
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof 
directly
+{

aaron.ballman wrote:
> I think this is defensible. The wording in the standard is "If the specified 
> type defines a new type or if the specified member is a bit-field, the 
> behavior is undefined." and the specified type in this case is `struct A`; 
> that `struct A` happens to also define `struct B` is immaterial.
> 
> However, the intent behind the change to the rule is to support older 
> implementations of `offsetof` to protect them from having to deal with a case 
> like: `offsetof(struct S { int a, b }, b);` where `offsetof` is a macro and 
> thus the comma between `a` and `b` is treated as a separator. So there's a 
> part of me that wonders if we want to also support diagnosing this case. But 
> then we'd have to look at the declarator context more recursively to see 
> whether any of the contexts on the stack are an `offsetof` context and that 
> might be tricky.
> 
> Thoughts?
FWIW, gcc seems just rejects all definitions in this context. (Perhaps during 
Parsing the statements). If we add a bool state to the Parser (just using RAII 
object as before) struct B will trigger diagnostic error because the state 
"ParsingOffsetof" is passed into inner declaration.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

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


[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-12 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459634.
inclyc added a comment.

git-clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof directly
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -3584,6 +3584,7 @@
   [[fallthrough]];
 case DeclaratorContext::TypeName:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   Error = 15; // Generic
   break;
 case DeclaratorContext::File:
@@ -3695,6 +3696,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   DiagID = diag::err_type_defined_in_type_specifier;
   break;
 case DeclaratorContext::Prototype:
@@ -4784,6 +4786,7 @@
 case DeclaratorContext::FunctionalCast:
 case DeclaratorContext::RequiresExpr:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // Don't infer in these contexts.
   break;
 }
@@ -5836,6 +5839,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // FIXME: We may want to allow parameter packs in block-literal contexts
   // in the future.
   S.Diag(D.getEllipsisLoc(),
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16257,7 +16257,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinBuiltinOffsetof) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17030,6 +17030,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinBuiltinOffsetof && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,8 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
-TypeResult Ty = ParseTypeName();
+TypeResult Ty =
+ParseTypeName(/*Range=*/nullptr, DeclaratorContext::OffsetOf);
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-12 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459633.
inclyc added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof directly
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -3584,6 +3584,7 @@
   [[fallthrough]];
 case DeclaratorContext::TypeName:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   Error = 15; // Generic
   break;
 case DeclaratorContext::File:
@@ -3695,6 +3696,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   DiagID = diag::err_type_defined_in_type_specifier;
   break;
 case DeclaratorContext::Prototype:
@@ -4784,6 +4786,7 @@
 case DeclaratorContext::FunctionalCast:
 case DeclaratorContext::RequiresExpr:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // Don't infer in these contexts.
   break;
 }
@@ -5836,6 +5839,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // FIXME: We may want to allow parameter packs in block-literal contexts
   // in the future.
   S.Diag(D.getEllipsisLoc(),
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16257,7 +16257,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinBuiltinOffsetof) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17030,6 +17030,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinBuiltinOffsetof && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,8 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
-TypeResult Ty = ParseTypeName();
+TypeResult Ty =
+ParseTypeName(/*Range=*/nullptr, DeclaratorContext::OffsetOf);
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-12 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459458.
inclyc added a comment.

Use declaration context


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // no-error, struct B is not defined within __builtin_offsetof directly
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -3584,6 +3584,7 @@
   [[fallthrough]];
 case DeclaratorContext::TypeName:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   Error = 15; // Generic
   break;
 case DeclaratorContext::File:
@@ -3695,6 +3696,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   DiagID = diag::err_type_defined_in_type_specifier;
   break;
 case DeclaratorContext::Prototype:
@@ -4784,6 +4786,7 @@
 case DeclaratorContext::FunctionalCast:
 case DeclaratorContext::RequiresExpr:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // Don't infer in these contexts.
   break;
 }
@@ -5836,6 +5839,7 @@
 case DeclaratorContext::TemplateArg:
 case DeclaratorContext::TemplateTypeArg:
 case DeclaratorContext::Association:
+case DeclaratorContext::OffsetOf:
   // FIXME: We may want to allow parameter packs in block-literal contexts
   // in the future.
   S.Diag(D.getEllipsisLoc(),
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinBuiltinOffsetof) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinBuiltinOffsetof && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,8 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
-TypeResult Ty = ParseTypeName();
+TypeResult Ty =
+ParseTypeName(/*Range*/ nullptr, DeclaratorContext::OffsetOf);
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459248.
inclyc added a comment.

Use RAII object to maintain the Parser state

> have you explored making a new DeclSpecContext and modifying 
> isDefiningTypeSpecifierContext()? I think that would likely be a cleaner 
> approach.

Emm, I've tried passing a DeclaratorContext into `ParseTypeName()`

  SourceLocation TypeLoc = Tok.getLocation();
  InBuiltInOffsetOfBaseRAIIObject InOffsetof(*this, true);
  TypeResult Ty = ParseTypeName(nullptr, /*Context=???*/); 

But defining a new DeclaratorContext I have to complete a bunch of `case`
statements.

  // Parser.h
  static bool isTypeSpecifier(DeclSpecContext DSC);
  static AllowDefiningTypeSpec isDefiningTypeSpecifierContext(DeclSpecContext 
DSC, bool IsCPlusPlus);
  static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC);
  /* ... */

And I think it is somehow strange to determine these properties within
__builtin_offsetof()? I'm not sure if it is really appropriate to define a
special context for a built-in function. This place should only need to
forbidden definitions, right?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinOffsetOf && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,6 +2579,7 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
+InBuiltInOffsetOfBaseRAIIObject InOffsetof(*this, true);
 TypeResult Ty = ParseTypeName();
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC == DeclSpecContext::DSC_type_specifier,
 DSC == DeclSpecContext::DSC_template_param ||
 DSC == DeclSpecContext::DSC_template_type_arg,
-);
+, InBuiltInOffsetOfBase);
 
 // If ActOnTag said the type was dependent, try again with the
 // less common call.
Index: clang/include/clang/Sema/Sema.h
===
--- 

[PATCH] D133609: [Sema] compat warning of using deduced type in non-type template parameter

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/SemaCXX/template-nontype-args-compat.cpp:1
+// RUN: %clang_cc1 -fsyntax-only -Wpre-c++20-compat -std=c++20 -verify=cpp20 
%s 
+

I cannot find other tests of compatibility warnings though. Is it necessary to 
add such tests here? (in subsequent patches)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133609

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


[PATCH] D133609: [Sema] compat warning of using deduced type in non-type template parameter

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
inclyc added reviewers: aaron.ballman, mizvekov, clang-language-wg.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Seems we are missing C++20 compatibility warning of using deduced type
(e.g. some template class) as a non-type template parameter. Before this
patch the following code crashes clang.

  template
  struct DC {};
  
  template // using deduced type, but considered as "auto" type
  auto test() {}

It triggered warn_cxx14_compat_template_nontype_parm_auto_type. However
there is no such "auto" type at all.

Using deduced type within non-type template parameter was introduced in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf.

This patch create a new compatibility diagnostic message for this.

Fixes: https://github.com/llvm/llvm-project/issues/57643


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133609

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaCXX/template-nontype-args-compat.cpp


Index: clang/test/SemaCXX/template-nontype-args-compat.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/template-nontype-args-compat.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -Wpre-c++20-compat -std=c++20 -verify=cpp20 
%s 
+
+namespace DeducedClass {
+template
+struct DC {};
+
+template // cpp20-warning{{non-type template parameters declared with 
'DC' are incompatible with C++ standards before C++20}}
+auto test() {}
+} // namespace DeducedClass
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -1532,9 +1532,17 @@
   CheckValidDeclSpecifiers();
 
   if (TInfo->getType()->isUndeducedType()) {
-Diag(D.getIdentifierLoc(),
- diag::warn_cxx14_compat_template_nontype_parm_auto_type)
-  << QualType(TInfo->getType()->getContainedAutoType(), 0);
+if (TInfo->getType()->getContainedAutoType()) {
+  // template
+  Diag(D.getIdentifierLoc(),
+   diag::warn_cxx14_compat_template_nontype_parm_auto_type)
+  << QualType(TInfo->getType()->getContainedAutoType(), 0);
+} else {
+  // template
+  Diag(D.getIdentifierLoc(),
+   diag::warn_cxx17_compat_template_nontype_parm_deduced_class)
+  << TInfo->getType();
+}
   }
 
   assert(S->isTemplateParamScope() &&
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4833,6 +4833,10 @@
   "non-type template parameter of type %0 is incompatible with "
   "C++ standards before C++20">,
   DefaultIgnore, InGroup;
+def warn_cxx17_compat_template_nontype_parm_deduced_class : Warning<
+  "non-type template parameters declared with %0 are incompatible with C++ "
+  "standards before C++20">,
+  DefaultIgnore, InGroup;
 def warn_cxx14_compat_template_nontype_parm_auto_type : Warning<
   "non-type template parameters declared with %0 are incompatible with C++ "
   "standards before C++17">,
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -95,6 +95,9 @@
   `Issue 57169 `_
 - Clang configuration files are now read through the virtual file system
   rather than the physical one, if these are different.
+- Fix `Issue 57643 `_.
+  Missing C++20 compatibility warning of deduced type as non-type template
+  parameters.
 
 
 Improvements to Clang's diagnostics


Index: clang/test/SemaCXX/template-nontype-args-compat.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/template-nontype-args-compat.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -Wpre-c++20-compat -std=c++20 -verify=cpp20 %s 
+
+namespace DeducedClass {
+template
+struct DC {};
+
+template // cpp20-warning{{non-type template parameters declared with 'DC' are incompatible with C++ standards before C++20}}
+auto test() {}
+} // namespace DeducedClass
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -1532,9 +1532,17 @@
   CheckValidDeclSpecifiers();
 
   if (TInfo->getType()->isUndeducedType()) {
-Diag(D.getIdentifierLoc(),
- diag::warn_cxx14_compat_template_nontype_parm_auto_type)
-  << QualType(TInfo->getType()->getContainedAutoType(), 0);
+if 

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459039.
inclyc added a comment.

Use double backquotes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinOffsetOf && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,9 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
+InBuiltInOffsetOfBase = true;
 TypeResult Ty = ParseTypeName();
+InBuiltInOffsetOfBase = false;
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC == DeclSpecContext::DSC_type_specifier,
 DSC == DeclSpecContext::DSC_template_param ||
 DSC == DeclSpecContext::DSC_template_type_arg,
-);
+, InBuiltInOffsetOfBase);
 
 // If ActOnTag said the type was dependent, try again with the
 // less common call.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3273,7 +3273,8 @@
  bool , SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ bool IsWithinOffsetOf = false);
 
   Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
 unsigned TagSpec, SourceLocation TagLoc,
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -246,6 +246,9 @@
   /// function call.
   bool CalledSignatureHelp = false;
 
+  /// Parsing a type within __builtin_offsetof.
+  bool InBuiltInOffsetOfBase = false;
+
   /// The "depth" of the template parameters currently being parsed.
   

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 459037.
inclyc added a comment.

Add release notes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133574

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinOffsetOf && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,9 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
+InBuiltInOffsetOfBase = true;
 TypeResult Ty = ParseTypeName();
+InBuiltInOffsetOfBase = false;
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC == DeclSpecContext::DSC_type_specifier,
 DSC == DeclSpecContext::DSC_template_param ||
 DSC == DeclSpecContext::DSC_template_type_arg,
-);
+, InBuiltInOffsetOfBase);
 
 // If ActOnTag said the type was dependent, try again with the
 // less common call.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3273,7 +3273,8 @@
  bool , SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ bool IsWithinOffsetOf = false);
 
   Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
 unsigned TagSpec, SourceLocation TagLoc,
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -246,6 +246,9 @@
   /// function call.
   bool CalledSignatureHelp = false;
 
+  /// Parsing a type within __builtin_offsetof.
+  bool InBuiltInOffsetOfBase = false;
+
   /// The "depth" of the template parameters currently being parsed.
   

[PATCH] D133574: [C2x] reject type definitions in offsetof

2022-09-09 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
Herald added a project: All.
inclyc updated this revision to Diff 459034.
inclyc added a comment.
inclyc added reviewers: aaron.ballman, clang-language-wg.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Apply clang-format


https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm made very
clear that it is an UB having type definitions with in offsetof. After
this patch clang will reject any type definitions in __builtin_offsetof.

Fixes https://github.com/llvm/llvm-project/issues/57065

I'm not sure this is a correct bug fix, because adding a new bool state
to Parser just for supporting this seems ugly. I've tried creating a new
DeclaratorContext, though.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133574

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Parser/declarators.c
  clang/test/Sema/offsetof.c

Index: clang/test/Sema/offsetof.c
===
--- clang/test/Sema/offsetof.c
+++ clang/test/Sema/offsetof.c
@@ -70,3 +70,16 @@
   return __builtin_offsetof(Array, array[*(int*)0]); // expected-warning{{indirection of non-volatile null pointer}} expected-note{{__builtin_trap}}
 }
 
+// Reject definitions in __builtin_offsetof
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
+int test_definition(void) {
+  return __builtin_offsetof(struct A // expected-error{{'struct A' cannot be defined in '__builtin_offsetof'}} 
+  { 
+int a;
+struct B // expected-error{{'struct B' cannot be defined in '__builtin_offsetof'}}
+{
+  int c;
+  int d;
+} x;
+  }, a);
+}
Index: clang/test/Parser/declarators.c
===
--- clang/test/Parser/declarators.c
+++ clang/test/Parser/declarators.c
@@ -80,10 +80,6 @@
 struct test10 { int a; } static test10x;
 struct test11 { int a; } const test11x;
 
-// PR6216
-void test12(void) {
-  (void)__builtin_offsetof(struct { char c; int i; }, i);
-}
 
 // rdar://7608537
 struct test13 { int a; } (test13x);
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16254,7 +16254,7 @@
  SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody) {
+ SkipBodyInfo *SkipBody, bool IsWithinOffsetOf) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
   assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17027,6 +17027,12 @@
cast_or_null(PrevDecl));
   }
 
+  if (IsWithinOffsetOf && TUK == TUK_Definition) {
+Diag(New->getLocation(), diag::err_type_defined_in_offsetof)
+<< Context.getTagDeclType(New);
+Invalid = true;
+  }
+
   // C++11 [dcl.type]p3:
   //   A type-specifier-seq shall not define a class or enumeration [...].
   if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
Index: clang/lib/Parse/ParseExpr.cpp
===
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -2579,7 +2579,9 @@
   }
   case tok::kw___builtin_offsetof: {
 SourceLocation TypeLoc = Tok.getLocation();
+InBuiltInOffsetOfBase = true;
 TypeResult Ty = ParseTypeName();
+InBuiltInOffsetOfBase = false;
 if (Ty.isInvalid()) {
   SkipUntil(tok::r_paren, StopAtSemi);
   return ExprError();
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2030,7 +2030,7 @@
 DSC == DeclSpecContext::DSC_type_specifier,
 DSC == DeclSpecContext::DSC_template_param ||
 DSC == DeclSpecContext::DSC_template_type_arg,
-);
+, InBuiltInOffsetOfBase);
 
 // If ActOnTag said the type was dependent, try again with the
 // less common call.
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3273,7 +3273,8 @@
  bool , SourceLocation ScopedEnumKWLoc,
  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
  bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ bool IsWithinOffsetOf = false);
 

[PATCH] D132952: [Sema] disable -Wvla for function array parameters

2022-09-06 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> Yeah, that's a different way of delineating than I was thinking originally 
> and it's worth more thought. I was thinking the separation would be "this is 
> a VLA" (for people who want to avoid all VLA stack allocations due to the 
> security concerns) and "this is a portability concern" (for people who want 
> to port to older language standards, C++, other compilers).

I think it is a good idea to separate `-Wvla` into `-Wvla-portability`(warnings 
on portability) and `-Wvla-stack` (warnings on stack allocations, security 
issue). Report `-Wvla-portability` if compilers implementations in practice 
don't support any `vla` syntax especially in C89 mode and report `-Wvla-stack` 
if it causes stack allocations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132952

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


[PATCH] D132952: [Sema] disable -Wvla for function array parameters

2022-09-04 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/Sema/warn-vla.c:8-12
+void test2(int n, int v[n]) { // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
 }

aaron.ballman wrote:
> The diagnostic there is rather unfortunate because we're not using a 
> variable-length array in this case.
Emm, I'm not clear about whether we should consider this a VLA, and generates 
`-Wvla-extensions`. Is `v[n]` literally a variable-length array? (in source 
code) So it seems to me that we should still report c89 incompatibility 
warnings?



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132952

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


[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-09-02 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:5340
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new

Maybe we can make a new `error` diagnostic definition and fire that here?



Comment at: clang/test/Parser/c2x-attributes.c:146
+// Ensure that '::' outside of attributes does not crash and is not treated as 
scope
+double n::v; // expected-error {{expected ';' after top level declarator}}

Could we improve this diagnostic message? 
```
expected ';' after top level declarator}
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133248

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


[PATCH] D133197: [clang] Fix crash when parsing scanf format string with missing arguments

2022-09-02 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a reviewer: aaron.ballman.
inclyc accepted this revision.
inclyc added a subscriber: aaron.ballman.
inclyc added a comment.
This revision is now accepted and ready to land.

Thanks @serge-sans-paille! Basically LGTM. Maybe we need to backport this patch 
though? @aaron.ballman


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133197

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


[PATCH] D133085: [clang] trim trailing space in format tests. NFC

2022-09-01 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

Thank you for your patience and detailed explanation! Sorry for waste your time 
though (


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133085

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


[PATCH] D133085: [clang] trim trailing space in format tests. NFC

2022-08-31 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D133085#3763198 , @ChuanqiXu wrote:

> Do you have commit access? If you have, I remember LLVM encourages to land 
> such fixes directly without reviewed. (+ @aaron.ballman to make sure)

Thanks! I'm just not sure whether these changes are necessary or not. :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133085

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


[PATCH] D133085: [clang] trim trailing space in format tests. NFC

2022-08-31 Thread YingChi Long via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5ee51e815425: [clang] trim trailing space in format tests. 
NFC (authored by inclyc).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133085

Files:
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-scanf.c

Index: clang/test/Sema/format-strings-scanf.c
===
--- clang/test/Sema/format-strings-scanf.c
+++ clang/test/Sema/format-strings-scanf.c
@@ -12,7 +12,7 @@
   unsigned int : (int)0,   \
   unsigned short : (short)0,   \
   unsigned char : (signed char)0))
-typedef __SSIZE_TYPE__ ssize_t; 
+typedef __SSIZE_TYPE__ ssize_t;
 
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #define __UNSIGNED_PTRDIFF_TYPE__  \
@@ -224,13 +224,13 @@
 
   ptrdiff_t p2 = 0;
   scanf("%td", ); // No warning.
-  
+
   double d2 = 0.;
   scanf("%td", ); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 
   ptrdiff_t p3 = 0;
   scanf("%tn", ); // No warning.
-  
+
   double d3 = 0.;
   scanf("%tn", ); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 }
Index: clang/test/FixIt/format.mm
===
--- clang/test/FixIt/format.mm
+++ clang/test/FixIt/format.mm
@@ -19,11 +19,11 @@
 
   NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", 0x260300);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
Index: clang/test/FixIt/format.m
===
--- clang/test/FixIt/format.m
+++ clang/test/FixIt/format.m
@@ -37,7 +37,7 @@
   // CHECK: fix-it:"{{.*}}":{34:11-34:13}:"%s"
 }
 
-void test_object_correction (id x) {  
+void test_object_correction (id x) {
   NSLog(@"%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'id'}}
   NSLog(@"%s", x); // expected-warning{{format specifies type 'char *' but the argument has type 'id'}}
   NSLog(@"%lf", x); // expected-warning{{format specifies type 'double' but the argument has type 'id'}}
@@ -108,7 +108,7 @@
   NSLog(@"%c", c); // no-warning
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
 
-  
+
   NSLog(@"%s", s); // expected-warning{{format specifies type 'char *' but the argument has type 'signed char'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
 
@@ -197,11 +197,11 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
 
   typedef unsigned short unichar;
-  
+
   NSLog(@"%C", 0x260300);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", data ? 0x2F : 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)("
@@ -239,7 +239,7 @@
 
   printf("%zd", 0.f); // expected-warning-re{{format specifies type 'ssize_t' (aka '{{.+}}') but the argument has type 'float'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
-  
+
   short x;
 #if !defined(__ANDROID__) && !defined(__Fuchsia__)
   printf("%zn", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'short *'}}
@@ -266,7 +266,7 @@
 
   printf("%tu", 0.f); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
-  
+
   ptrdiff_t p2 = 0;
   printf("%td", p2);  // No warning.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D133085: [clang] trim trailing space in format tests. NFC

2022-08-31 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
inclyc added a reviewer: clang-language-wg.
Herald added a project: All.
inclyc requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Found in https://reviews.llvm.org/D132568


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133085

Files:
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-scanf.c

Index: clang/test/Sema/format-strings-scanf.c
===
--- clang/test/Sema/format-strings-scanf.c
+++ clang/test/Sema/format-strings-scanf.c
@@ -12,7 +12,7 @@
   unsigned int : (int)0,   \
   unsigned short : (short)0,   \
   unsigned char : (signed char)0))
-typedef __SSIZE_TYPE__ ssize_t; 
+typedef __SSIZE_TYPE__ ssize_t;
 
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #define __UNSIGNED_PTRDIFF_TYPE__  \
@@ -224,13 +224,13 @@
 
   ptrdiff_t p2 = 0;
   scanf("%td", ); // No warning.
-  
+
   double d2 = 0.;
   scanf("%td", ); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 
   ptrdiff_t p3 = 0;
   scanf("%tn", ); // No warning.
-  
+
   double d3 = 0.;
   scanf("%tn", ); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 }
Index: clang/test/FixIt/format.mm
===
--- clang/test/FixIt/format.mm
+++ clang/test/FixIt/format.mm
@@ -19,11 +19,11 @@
 
   NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", 0x260300);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
Index: clang/test/FixIt/format.m
===
--- clang/test/FixIt/format.m
+++ clang/test/FixIt/format.m
@@ -37,7 +37,7 @@
   // CHECK: fix-it:"{{.*}}":{34:11-34:13}:"%s"
 }
 
-void test_object_correction (id x) {  
+void test_object_correction (id x) {
   NSLog(@"%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'id'}}
   NSLog(@"%s", x); // expected-warning{{format specifies type 'char *' but the argument has type 'id'}}
   NSLog(@"%lf", x); // expected-warning{{format specifies type 'double' but the argument has type 'id'}}
@@ -108,7 +108,7 @@
   NSLog(@"%c", c); // no-warning
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
 
-  
+
   NSLog(@"%s", s); // expected-warning{{format specifies type 'char *' but the argument has type 'signed char'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
 
@@ -197,11 +197,11 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
 
   typedef unsigned short unichar;
-  
+
   NSLog(@"%C", 0x260300);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
-  
+
   NSLog(@"%C", data ? 0x2F : 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)("
@@ -239,7 +239,7 @@
 
   printf("%zd", 0.f); // expected-warning-re{{format specifies type 'ssize_t' (aka '{{.+}}') but the argument has type 'float'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
-  
+
   short x;
 #if !defined(__ANDROID__) && !defined(__Fuchsia__)
   printf("%zn", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'short *'}}
@@ -266,7 +266,7 @@
 
   printf("%tu", 0.f); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
-  
+
   ptrdiff_t p2 = 0;
   printf("%td", p2);  // No warning.
 
___
cfe-commits mailing list

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-31 Thread YingChi Long 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 rGe3bd67eddf65: [clang][Sema] check default argument 
promotions for printf (authored by inclyc).

Changed prior to commit:
  https://reviews.llvm.org/D132568?vs=457153=457157#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 'short'}}
+  printf("%f", us); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned short'}}
+
+  // character literals
+  // In C language engineering practice, printing a character literal with %hhd or %d is common, but %hd may be misuse.
+  printf("%hhu", 'a'); // no-warning
+  printf("%hhd", 'a'); // no-warning
+  printf("%hd", 'a'); // expected-warning{{format specifies type 'short' but the argument has type 'char'}}
+  printf("%hu", 'a'); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'char'}}
+  printf("%d", 'a'); // no-warning
+  printf("%u", 'a'); // no-warning
+  
+  // pointers
+  printf("%s", i); // expected-warning{{format 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-31 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 457153.
inclyc added a comment.

Update comments according to review feedback


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 'short'}}
+  printf("%f", us); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned short'}}
+
+  // character literals
+  // In C language engineering practice, printing a character literal with %hhd or %d is common, but %hd may be misuse.
+  printf("%hhu", 'a'); // no-warning
+  printf("%hhd", 'a'); // no-warning
+  printf("%hd", 'a'); // expected-warning{{format specifies type 'short' but the argument has type 'char'}}
+  printf("%hu", 'a'); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'char'}}
+  printf("%d", 'a'); // no-warning
+  printf("%u", 'a'); // no-warning
+  
+  // pointers
+  printf("%s", i); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
+}
Index: clang/test/Sema/format-strings-scanf.c
===
--- 

[PATCH] D132952: [Sema] disable -Wvla for function array parameters

2022-08-30 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:1760
+// Special builder emitting no diagnostics
+SemaDiagnosticBuilder(Sema ) : S(S) {}
 SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,

erichkeane wrote:
> I haven't looked particularly closely, but this doesn't seem right to me.  
> There is already the 'K_Nop' diagnostic Kind (see the line below), that we 
> should look at the uses of.
I've tried using the following constructor, I have to to pass in a series of 
redundant parameters (such as `DiagID` and `Loc`), which makes it strange to 
construct a Builder emitting no error message at all?

e.g.

```
Sema::SemaDiagnosticBuilder(Sema::SemaDiagnosticBuilder::Kind::K_Nop, Loc, 0,
  nullptr, S);
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132952

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


[PATCH] D132952: [Sema] disable -Wvla for function array parameters

2022-08-30 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
inclyc added a reviewer: aaron.ballman.
Herald added a project: All.
inclyc added reviewers: rsmith, clang-language-wg.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixes: https://github.com/llvm/llvm-project/issues/57098


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132952

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaType.cpp
  clang/test/Sema/warn-vla.c


Index: clang/test/Sema/warn-vla.c
===
--- clang/test/Sema/warn-vla.c
+++ clang/test/Sema/warn-vla.c
@@ -5,8 +5,18 @@
   int v[n]; // expected-warning {{variable length array}}
 }
 
-void test2(int n, int v[n]) { // expected-warning {{variable length array}}
+void test2(int n, int v[n]) { // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
 }
 
-void test3(int n, int v[n]); // expected-warning {{variable length array}}
+void test3(int n, int v[n]); // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
 
+void test4(int n, int v[][*]); // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2367,9 +2367,11 @@
 unsigned VLADiag;
 bool VLAIsError;
 bool IsVLA = false;
+bool SuppressNotICEVLA = false;
 
-VLADiagnoser(unsigned VLADiag, bool VLAIsError)
-: VLADiag(VLADiag), VLAIsError(VLAIsError) {}
+VLADiagnoser(unsigned VLADiag, bool VLAIsError, bool SuppressNotICEVLA)
+: VLADiag(VLADiag), VLAIsError(VLAIsError),
+  SuppressNotICEVLA(SuppressNotICEVLA) {}
 
 Sema::SemaDiagnosticBuilder diagnoseNotICEType(Sema , SourceLocation Loc,
QualType T) override {
@@ -2379,14 +2381,18 @@
 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema ,
SourceLocation Loc) override {
   IsVLA = !VLAIsError;
-  return S.Diag(Loc, VLADiag);
+  if (!SuppressNotICEVLA)
+return S.Diag(Loc, VLADiag);
+  return Sema::SemaDiagnosticBuilder(S);
 }
 
 Sema::SemaDiagnosticBuilder diagnoseFold(Sema ,
  SourceLocation Loc) override {
   return S.Diag(Loc, diag::ext_vla_folded_to_constant);
 }
-  } Diagnoser(VLADiag, VLAIsError);
+  } Diagnoser(VLADiag, VLAIsError,
+  S.getCurScope()->isFunctionPrototypeScope() &&
+  VLADiag == diag::warn_vla_used);
 
   ExprResult R =
   S.VerifyIntegerConstantExpression(ArraySize, , Diagnoser);
@@ -2528,7 +2534,9 @@
   llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
   if (!ArraySize) {
 if (ASM == ArrayType::Star) {
-  Diag(Loc, VLADiag);
+  if (!(getCurScope()->isFunctionPrototypeScope() &&
+VLADiag == diag::warn_vla_used))
+Diag(Loc, VLADiag);
   if (VLAIsError)
 return QualType();
 
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1756,6 +1756,8 @@
   K_Deferred
 };
 
+// Special builder emitting no diagnostics
+SemaDiagnosticBuilder(Sema ) : S(S) {}
 SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
   FunctionDecl *Fn, Sema );
 SemaDiagnosticBuilder(SemaDiagnosticBuilder &);


Index: clang/test/Sema/warn-vla.c
===
--- clang/test/Sema/warn-vla.c
+++ clang/test/Sema/warn-vla.c
@@ -5,8 +5,18 @@
   int v[n]; // expected-warning {{variable length array}}
 }
 
-void test2(int n, int v[n]) { // expected-warning {{variable length array}}
+void test2(int n, int v[n]) { // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
 }
 
-void test3(int n, int v[n]); // expected-warning {{variable length array}}
+void test3(int n, int v[n]); // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
 
+void test4(int n, int v[][*]); // c99 no-warning
+#if __STDC_VERSION__ < 199901L
+// expected-warning@-2{{variable length arrays are a C99 feature}}
+#endif
Index: clang/lib/Sema/SemaType.cpp
===
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2367,9 +2367,11 @@
 unsigned VLADiag;
 bool VLAIsError;
 bool IsVLA = false;
+bool SuppressNotICEVLA = false;
 
-

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-27 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 456111.
inclyc added a comment.

Delete extra newline.

Currently this patch has not fully implemented `wchar_t` related support, this
type seems to be even platform dependent in C language, if possible, maybe we
can consider support in subsequent patches?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 'short'}}
+  printf("%f", us); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned short'}}
+
+  // character literals
+  // In C language engineering practice, printing a character literal with %hhd or %d is common, but %hd may be misuse.
+  printf("%hhu", 'a'); // no-warning
+  printf("%hhd", 'a'); // no-warning
+  printf("%hd", 'a'); // expected-warning{{format specifies type 'short' but the argument has type 'char'}}
+  printf("%hu", 'a'); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'char'}}
+  printf("%d", 'a'); // no-warning
+  printf("%u", 'a'); // no-warning
+  
+  // pointers
+  printf("%s", i); // expected-warning{{format specifies type 'char *' but the 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455898.
inclyc added a comment.

Update comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,58 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 'short'}}
+  printf("%f", us); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned short'}}
+
+  // character literals
+  // In C language engineering practice, printing a character literal with %hhd or %d is common, but %hd may be misuse.
+  printf("%hhu", 'a'); // no-warning
+  printf("%hhd", 'a'); // no-warning
+  printf("%hd", 'a'); // expected-warning{{format specifies type 'short' but the argument has type 'char'}}
+  printf("%hu", 'a'); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'char'}}
+  printf("%d", 'a'); // no-warning
+  printf("%u", 'a'); // no-warning
+
+
+  // pointers
+  printf("%s", i); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
+}
Index: clang/test/Sema/format-strings-scanf.c
===
--- clang/test/Sema/format-strings-scanf.c
+++ 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/lib/AST/FormatString.cpp:367
+case BuiltinType::Char_U:
+case BuiltinType::Bool:
+  return Match;

aaron.ballman wrote:
> inclyc wrote:
> > aaron.ballman wrote:
> > > Isn't this a match promotion as well? e.g. `printf("%hhd", (_Bool)0);` 
> > > where the `_Bool` is promoted to `int` but then cast back down to a char 
> > > type (which seems rather unlikely to be a type confusion issue).
> > Hmm? `_Bool` just matches `AnyCharTy` perfectly. `MatchPromotion` means the 
> > types having **different** length and they can be considered as "partially 
> > matched" because of promotions). 
> > 
> > Isn't `_Bool`  and `AnyChar`  here just have the same length?
> > Hmm? _Bool just matches AnyCharTy perfectly. MatchPromotion means the types 
> > having different length and they can be considered as "partially matched" 
> > because of promotions).
> >
> > Isn't _Bool and AnyChar here just have the same length?
> 
> `_Bool` is not a character type, so it doesn't match `AnyCharTy` perfectly. 
> The size can be the same but they're still different types.
I've add `case BuiltinType::Bool:` back to preserve 
https://reviews.llvm.org/D66856


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-26 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455871.
inclyc added a comment.

Add LangOpts so we keep the Obj-C behavior of clang just as-is.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,58 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 'short'}}
+  printf("%f", us); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned short'}}
+
+  // character literals
+  // In C language engineering practice, printing a character literal with %hhd or %d is common, but %hd may be misuse.
+  printf("%hhu", 'a'); // no-warning
+  printf("%hhd", 'a'); // no-warning
+  printf("%hd", 'a'); // expected-warning{{format specifies type 'short' but the argument has type 'char'}}
+  printf("%hu", 'a'); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'char'}}
+  printf("%d", 'a'); // no-warning
+  printf("%u", 'a'); // no-warning
+
+
+  // pointers
+  printf("%s", i); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
+}
Index: clang/test/Sema/format-strings-scanf.c
===
--- 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455793.
inclyc added a comment.

Trim whitespace in format.mm


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,58 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:10127-10129
+if (ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
+ImplicitMatch != ArgType::NoMatchTypeConfusion &&
+!IsCharacterLiteralInt)

nickdesaulniers wrote:
> There's something about this conditional...I can't quite put my finger on.
> 
> Isn't `ImplicitMatch` only updated in the `const ImplicitCastExpr *ICE = 
> dyn_cast(E)` branch above, where `IsCharacterLiteralInt` 
> cannot be?
> 
> Simultaneously, isn't `IsCharacterLiteralInt` only updated in the `const 
> CharacterLiteral *CL = dyn_cast(E)` branch above, where 
> `ImplicitMatch` cannot be?
> 
> I wonder if we should instead hoist:
> ```
> if (Match == ArgType::MatchPromotion) {
>   if (ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
>   ImplicitMatch != ArgType::NoMatchTypeConfusion)
> return true;
>   Match = ArgType::NoMatch;
> }
> ```
> into the `const ImplicitCastExpr *ICE = dyn_cast(E)` branch 
> after `ImplicitMatch` is updated.
> 
> Then hoist
> ```
> if (Match == ArgType::MatchPromotion)
>   return true;
> ```
> into the `const CharacterLiteral *CL = dyn_cast(E)` branch 
> after `IsCharacterLiteralInt` is updated? Then we could delete the 
> `IsCharacterLiteralInt` variable perhaps?
> There's something about this conditional...I can't quite put my finger on.
> 
> Isn't `ImplicitMatch` only updated in the `const ImplicitCastExpr *ICE = 
> dyn_cast(E)` branch above, where `IsCharacterLiteralInt` 
> cannot be?
> 
> Simultaneously, isn't `IsCharacterLiteralInt` only updated in the `const 
> CharacterLiteral *CL = dyn_cast(E)` branch above, where 
> `ImplicitMatch` cannot be?
> 
> I wonder if we should instead hoist:
> ```
> if (Match == ArgType::MatchPromotion) {
>   if (ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
>   ImplicitMatch != ArgType::NoMatchTypeConfusion)
> return true;
>   Match = ArgType::NoMatch;
> }
> ```
> into the `const ImplicitCastExpr *ICE = dyn_cast(E)` branch 
> after `ImplicitMatch` is updated.


The control flow may not entering any of these branches at all, and if we have 
`Match == MatchPromotion` we depend on the origin value of `ImplicitMatch` to 
determine whether or not to discard the `MatchPromotion` property. For example, 

```
printf("%hd", 0);
```

We have `MatchPromotion` because the argument is an `int` and the format string 
specifies `signed short`, and we will not entering `ImplicitCastExpr` branch 
because the argument is an `int` already (so we don't need an "implicit cast")

> 
> Then hoist
> ```
> if (Match == ArgType::MatchPromotion)
>   return true;
> ```
> into the `const CharacterLiteral *CL = dyn_cast(E)` branch 
> after `IsCharacterLiteralInt` is updated? Then we could delete the 
> `IsCharacterLiteralInt` variable perhaps?

Thank you for this! I've hoisted this into `CharacterLiteralExpr` branch. And 
now `IsCharacterLiteralInt` is unnecessary.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455671.
inclyc added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,58 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the argument has type 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455645.
inclyc added a comment.

Remove wchar tests.

These tests may need to be re-added after we have implemented `wchar_t` checks 
in C


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,58 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/lib/AST/FormatString.cpp:401
+  if (const auto *BT = argTy->getAs()) {
+if (!Ptr) {
+  switch (BT->getKind()) {

nickdesaulniers wrote:
> aaron.ballman wrote:
> > It's a bit strange that we have two switches over the same `BT->getKind()` 
> > and the only difference is `!Ptr`; would it be easier to read if we 
> > combined the two switches into one and had logic in the individual cases 
> > for `Ptr` vs not `Ptr`?
> I almost made the same recommendation myself.  For the below switch pair, and 
> the pair above.
> It's a bit strange that we have two switches over the same `BT->getKind()` 
> and the only difference is `!Ptr`; would it be easier to read if we combined 
> the two switches into one and had logic in the individual cases for `Ptr` vs 
> not `Ptr`?

These two switch pairs have different functions. The lower one is only 
responsible for checking whether there is a signed or unsigned integer, and the 
upper one is checking whether there is a promotion (or type confusing). Will 
they be more difficult to understand if they are written together? 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455626.
inclyc added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,64 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+  wchar_t wc;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
+  printf("%f", sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+  printf("%f", uc); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}}
+  printf("%f", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}}
+  printf("%f", ss); // expected-warning{{format specifies type 'double' but the 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc marked 2 inline comments as done.
inclyc added inline comments.



Comment at: clang/lib/AST/FormatString.cpp:367
+case BuiltinType::Char_U:
+case BuiltinType::Bool:
+  return Match;

aaron.ballman wrote:
> Isn't this a match promotion as well? e.g. `printf("%hhd", (_Bool)0);` where 
> the `_Bool` is promoted to `int` but then cast back down to a char type 
> (which seems rather unlikely to be a type confusion issue).
Hmm? `_Bool` just matches `AnyCharTy` perfectly. `MatchPromotion` means the 
types having **different** length and they can be considered as "partially 
matched" because of promotions). 

Isn't `_Bool`  and `AnyChar`  here just have the same length?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/lib/AST/FormatString.cpp:422
+  case BuiltinType::Bool:
+// Don't warn printf("%hd", [char])
+// https://reviews.llvm.org/D66186

aaron.ballman wrote:
> The comment is talking about passing a `char` (promoted to `int`) then 
> printed as a `short` but the check is looking for the type to be printed as 
> an `int`; that doesn't seem like a type confusion situation so much as a 
> match due to promotion. Should the test below be looking for a short type 
> instead of an int type?
> The comment is talking about passing a `char` (promoted to `int`) then 
> printed as a `short` but the check is looking for the type to be printed as 
> an `int`; that doesn't seem like a type confusion situation so much as a 
> match due to promotion. Should the test below be looking for a short type 
> instead of an int type?

Sorry for this (sometimes shit happens). There is a lot of redundant logic in 
this place, I will upload the corrected code immediately.



Comment at: clang/test/Sema/format-strings-scanf.c:289-290
+  // ill-formed floats
+  scanf("%hf", // expected-warning{{length modifier 'h' results in undefined 
behavior or no effect with 'f' conversion specifier}}
+  ); // Is this a clang bug ?
+

aaron.ballman wrote:
> inclyc wrote:
> > aaron.ballman wrote:
> > > Is what a clang bug?
> > > 
> > > Also, what is with the "or no effect" in that wording? "This could cause 
> > > major issues or nothing bad at all might happen" is a very odd way to 
> > > word a diagnostic. :-D (Maybe something to look into improving in a later 
> > > patch.)
> > > Is what a clang bug?
> > 
> > Look at `sc` which is a `signed char`, but scanf need a pointer `float *`, 
> > I add this comment because I think there should be a warning like 
> > ```
> > format specifies type 'float *' but the argument has type 'signed short *'
> > ```
> > 
> > See printf tests below
> Oh I see what you're saying! There are two issues with the code: one is that 
> the format specifier itself is UB and the other is that the argument passed 
> to this confused format specifier does not agree.
> 
> To me, the priority is the invalid format specifier; unless the user corrects 
> that, we're not really certain what they were aiming to scan in. And I think 
> it's *probably* more likely that the user made a typo in the format specifier 
> instead of trying to scan a half float (or whatever they thought they were 
> scanning) into a `signed char`, so it seems defensible to silence the 
> mismatched specifier diagnostic.
> 
> WDYT?
```  
printf("%hf", // expected-warning{{length modifier 'h' results in undefined 
behavior or no effect with 'f' conversion specifier}}
  sc); // expected-warning{{format specifies type 'double' but the argument has 
type 'signed char'}}
```

Then clang seems to have two different behaviors to `printf` and `scanf`, and 
for `printf` it will give the kind of diagnosis I said. I don't think this 
problem is particularly serious, because the key point is that using `%hf` UB. 
So maybe we can just keep clang as-is? Or we should consider implement the same 
warning in `scanf` ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/test/FixIt/format.m:40
 
-void test_object_correction (id x) {  
+void test_object_correction (id x) {
   NSLog(@"%d", x); // expected-warning{{format specifies type 'int' but the 
argument has type 'id'}}

aaron.ballman wrote:
> It looks like some whitespace only changes snuck in.
> It looks like some whitespace only changes snuck in.

I'm sorry for this, do I need to discard these whitespace-only changes? Since 
this patch changes this file, is it my responsibility to keep other parts that 
don't belong to this patch unchanged, or am I correcting them by the way?



Comment at: clang/test/Sema/format-strings-scanf.c:289-290
+  // ill-formed floats
+  scanf("%hf", // expected-warning{{length modifier 'h' results in undefined 
behavior or no effect with 'f' conversion specifier}}
+  ); // Is this a clang bug ?
+

aaron.ballman wrote:
> Is what a clang bug?
> 
> Also, what is with the "or no effect" in that wording? "This could cause 
> major issues or nothing bad at all might happen" is a very odd way to word a 
> diagnostic. :-D (Maybe something to look into improving in a later patch.)
> Is what a clang bug?

Look at `sc` which is a `signed char`, but scanf need a pointer `float *`, I 
add this comment because I think there should be a warning like 
```
format specifies type 'float *' but the argument has type 'signed short *'
```

See printf tests below


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-25 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455485.
inclyc added a comment.

Fix CI issue


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455477.
inclyc added a comment.

comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455475.
inclyc added a comment.

Comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455474.
inclyc added a comment.

Add tests for character literals

I've noticed that Linus mentioned the following code triggered warning by
clang. (With a little modifications shown below)

Link: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=21f9c8a13bb2a0c24d9c6b86bc0896542a28c197

  printf("%hhd", 'a');
  printf("%hd", 'a');

character literals are `int` in C. So clang-14 generates warnings like this:

  local/format.c:9:20: warning: format specifies type 'char' but the argument 
has type 'int' [-Wformat]
  printf("%hhd", 'a');
     ^~~
  %d
  local/format.c:10:19: warning: format specifies type 'short' but the argument 
has type 'char' [-Wformat]
  printf("%hd", 'a');
  ~~~   ^~~
  %hhd
  2 warnings generated.

Ironically, we advise our users to change their source code, which leads to
another warning. I've added tests for this case, after this patch, only (%hd,
"char") will cause warnings. And clang will generate warning like this:

  local/format.c:10:19: warning: format specifies type 'short' but the argument 
has type 'char' [-Wformat]
  printf("%hd", 'a');
  ~~~   ^~~
  %hhd
  1 warning generated.

Use `%hd` with `char` is not reasonable. (Probabaly another misuse) So I kept
this warning as-is.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,57 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455459.
inclyc added a comment.

rm {}


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,48 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", i); // expected-warning{{format 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 455458.
inclyc added a comment.

Address comments & more tests & docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -819,13 +819,7 @@
 
   Unclear type relationship between a format specifier and its argument
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf;>N2562
-  
-Partial
-  Clang supports diagnostics checking format specifier validity, but
-  does not yet account for all of the changes in this paper, especially
-  regarding length modifiers like h and hh.
-
-  
+  Clang 16
 
 
 
Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,48 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+  short ss;
+  unsigned short us;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  // %ld %lld %llx
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned char'}}
+  printf("%lld", uc); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned char'}}
+  printf("%llx", i); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'int'}}
+
+  // ill formed spec for floats
+  printf("%hf", // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  sc); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}}
+
+  // for %hhd and `short` they are compatible by promotions but more likely misuse
+  printf("%hd", ss); // no-warning
+  printf("%hhd", ss); // expected-warning{{format specifies type 'char' but the argument has type 'short'}}
+  printf("%hu", us); // no-warning
+  printf("%hhu", ss); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+
+  // floats & integers are not compatible
+  printf("%f", 

[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> Do we want to encode that in `test_promotion` in 
> `clang/test/Sema/format-strings.c`? Seems like tests on shorts are missing.

Tests for short and char "incompatibility" could be found elsewhere in this 
file.

format-strings.c

  void should_understand_small_integers(void) {
printf("%hhu", (short) 10); // expected-warning{{format specifies type 
'unsigned char' but the argument has type 'short'}}
printf("%hu\n", (unsigned char)1); // warning with -Wformat-pedantic only
printf("%hu\n", (uint8_t)1);   // warning with -Wformat-pedantic only
  }
  /* ... */
  void test13(short x) {
char bel = 007;
printf("bel: '0%hhd'\n", bel); // no-warning
printf("x: '0%hhd'\n", x); // expected-warning {{format specifies type 
'char' but the argument has type 'short'}}
  }

Do I need to explicitly test again in the `test_promotion`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132568

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


[PATCH] D132568: [clang][Sema] check default argument promotions for printf

2022-08-24 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
inclyc added a reviewer: aaron.ballman.
Herald added a subscriber: emaste.
Herald added a project: All.
inclyc published this revision for review.
inclyc added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

https://reviews.llvm.org/D132266

This patch seems to ignore this scenario:

  printf("%hhf", [int])

Where we have length modifier `h`, and the argument type is `int`. Causes clang 
to suppress warnings about type mismatches between floats and integers.




Comment at: clang/test/FixIt/format.mm:10
 
   const wchar_t wchar_data = L'a';
   NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 
'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}

The language built-in `wchar_t` will be properly diagnosed.



Comment at: clang/test/SemaObjC/format-strings-objc.m:194
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 
'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
 }

This `wchar_t` is defined as `typedef __WCHAR_TYPE__ wchar_t;`. Actually it is 
`int` on my machine, I'm not sure if we should still report this warning as 
before, because it is just `int`, not a real `"wchar_t"`.


The main focus of this patch is to make ArgType::matchesType check for
possible default parameter promotions when the argType is not a pointer.
If so, no warning will be given for `int`, `unsigned int` types as
corresponding arguments to %hhd and %hd. However, the usage of %hhd
corresponding to short is relatively rare, and it is more likely to be a
misuse. This patch keeps the original behavior of clang like this as
much as possible, while making it more convenient to consider the
default arguments promotion.

Fixes https://github.com/llvm/llvm-project/issues/57102


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132568

Files:
  clang/include/clang/AST/FormatString.h
  clang/lib/AST/FormatString.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/FixIt/format.mm
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-scanf.c
  clang/test/Sema/format-strings.c
  clang/test/SemaObjC/format-strings-objc.m

Index: clang/test/SemaObjC/format-strings-objc.m
===
--- clang/test/SemaObjC/format-strings-objc.m
+++ clang/test/SemaObjC/format-strings-objc.m
@@ -80,7 +80,7 @@
 
 //  - Catch use of long long with int arguments.
 void rdar_7068334(void) {
-  long long test = 500;  
+  long long test = 500;
   printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
   CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}}
@@ -191,7 +191,7 @@
   NSLog(@"%C", data);  // no-warning
 
   const wchar_t wchar_data = L'a';
-  NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
+  NSLog(@"%C", wchar_data);  // no-warning
 }
 
 // Test that %@ works with toll-free bridging ().
@@ -273,7 +273,7 @@
 
 void testUnicode(void) {
   NSLog(@"%C", 0x2022); // no-warning
-  NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
+  NSLog(@"%C", 0x202200); // no-warning
 }
 
 // Test Objective-C modifier flags.
Index: clang/test/Sema/format-strings.c
===
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,28 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+void test_promotion(void) {
+  // Default argument promotions for *printf in N2562
+  // https://github.com/llvm/llvm-project/issues/57102
+  // N2562: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf
+  int i;
+  signed char sc;
+  unsigned char uc;
+  char c;
+
+  printf("%hhd %hd %d %hhd %hd %d", i, i, i, sc, sc, sc); // no-warning
+  printf("%hhd %hd %d %hhd %hd %d", uc, uc, uc, c, c, c); // no-warning
+
+  printf("%ld", i); // expected-warning{{format specifies type 'long' but the argument has type 'int'}}
+  printf("%lld", i); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
+  printf("%ld", sc); // expected-warning{{format specifies type 'long' but the argument has type 'signed char'}}
+  printf("%lld", sc); // expected-warning{{format specifies type 'long long' but the argument has type 'signed char'}}
+  printf("%ld", uc); // expected-warning{{format specifies 

[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

> format specifies type 'short' but the argument has type 'double' (promoted 
> from 'float')

I'm not sure about this. I'm curious about we just consider any integer with 
width less than or equal to `int` may be specified by `%hhd` ? (Because of 
default argument promotions). For example, we may expect `%hhd` could accept 
`int` `short` and `char`. And give diagnostics like

  format specifies integers with width less than or equal to 'int', but the 
argument has type 'double' (promoted from 'float')
  
  note: {info about why %hhd consumes argument like this}



> fwprintf shall behave as if it uses va_arg with a type argument naming the 
> type resulting from
> applying the default argument promotions to the type corresponding to the 
> conversion specification and
> then converting the result of the va_arg expansion to the type corresponding 
> to the conversion
> specification.



-

OpenCL seems to defined a series of length modifiers for vectors, Is it more 
reasonable to consider `hh` as fixed length (char) only? Because vectors are 
passed without argument promotions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

If some one use `%hhd` with an unmatched type argument. Should we emit diagnose 
like

  format specifies type 'int' but the argument has type 'WhateverType'

instead of

  format specifies type 'char' but the argument has type 'WhateverType'

?

It's seems that there are many regression tests about this. Should we keep the 
legacy behaviour?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D132266#3739618 , @aaron.ballman 
wrote:

> In D132266#3739600 , @inclyc wrote:
>
>> What I'm confusing is
>> Which of the following two explanations is the exact meaning of `hhd`?
>>
>> 1. consumes a 32-bit signed integer, then truncates it *inside* printf
>> 2. consumes an 8-bit signed integer
>>
>> If it is the case 1, we should not emit this warning, but N2562 said that it 
>> still seems to be 2 ?
>
> There's some confusion happening that we should clarify first. The sections 
> you've been quoting so far are for the behavior of `fscanf` not `fprintf` and 
> the requirements are different.
>
> For `fprintf`, `hhd` means that `fprintf` consumes an `int`-sized object by 
> calling effectively `signed char value = (signed char)va_arg(list, int);`.
> For `fscanf`, `hhd` means that `fscanf` consumes a pointer in which to store 
> the converted data by effectively calling `signed char *ptr = (signed char 
> *)va_arg(list, signed char *); *ptr = value;`
>
> This patch is currently handling only the `fprintf` cases and is not 
> addressing the `fscanf` ones.

Thanks! This completely solved my doubts. I mistakenly thought that `hhd` also 
corresponds to `signed char` in printf now. :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

What I'm confusing is
Which of the following two explanations is the exact meaning of `hhd`?

1. consumes a 32-bit signed integer, then truncates it *inside* printf
2. consumes an 8-bit signed integer

If it is the case 1, we should not emit this warning, but N2562 said that it 
still seems to be 2 ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

N2562.pdf:

> Modify 7.21.6.2p12:
> ...
>  Unless a length modifier is specified, t~~T~~he corresponding argument shall 
> be a pointer to int ~~signed integer~~.

Does this clarification statement mean that `hhd` should not be considered to 
correspond to `int`, but a `signed char`? If so, could this exactly imply that 
we have unmatched argument type? (i.e. `int` <--x--> `hhd` (signed char) )


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

2022-08-22 Thread YingChi Long via Phabricator via cfe-commits
inclyc added a comment.

In D132266#3739513 , @aaron.ballman 
wrote:

> Thanks for working on this @nickdesaulniers! I think we actually want to go a 
> slightly different direction than this and disable the diagnostics entirely. 
> Basically, we should be make sure the format specifier diagnostics are 
> accounting for the clarifications in 
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2562.pdf. So the `h` and 
> `hh` modifiers would not even be pedantic warnings in this case.
>
> This should also have a release note associated with it and if you think 
> you've completed support for N2562, the clang/www/c_status.html page should 
> update the `Partial` markings.

Sorry, I have some questions about this clarification agreement (currently 
working on N2562). The length modifier `hh` says in the standard that it should 
point to `signed char` or `unsigned char`, and if an `int` parameter is passed, 
why shouldn't we give such a warning? (even if it's pedantic somehow)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132266

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


[PATCH] D131892: [Sema] fix false -Wcomma being emitted from void returning functions

2022-08-16 Thread YingChi Long via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGccbc22cd8976: [Sema] fix false -Wcomma being emitted from 
void returning functions (authored by inclyc).

Changed prior to commit:
  https://reviews.llvm.org/D131892?vs=452767=452970#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131892

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/warn-comma-operator.cpp

Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,27 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void void_function_comma(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
+typedef void Void;
+Void typedef_func();
+
+void whatever() {
+  // We don't get confused about type aliases.
+  typedef_func(), int_func();
+  // Even function pointers don't confuse us.
+  void (*fp)() = void_func;
+  fp(), int_func();
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
@@ -296,4 +317,23 @@
   (void)T{}, 0;
   static_cast(T{}), 0;
 }
+
+namespace {
+
+// issue #57151
+
+struct S {
+  void mem() {}
+};
+
+void whatever() {
+  struct S s;
+  // Member function calls also work as expected.
+  s.mem(), int_func();
+  // As do lambda calls.
+  []() { return; }(), int_func();
+}
+
+} // namespace
+
 #endif  // ifdef __cplusplus
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returns void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,8 @@
 }
   }
 
+  if (const auto *CE = dyn_cast(E))
+return CE->getCallReturnType(Context)->isVoidType();
   return false;
 }
 
@@ -14014,7 +14018,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -73,7 +73,8 @@
   number of arguments cause an assertion fault.
 - Fix multi-level pack expansion of undeclared function parameters.
   This fixes `Issue 56094 `_.
-
+- Fix `#57151 `_.
+  ``-Wcomma`` is emitted for void returning functions.
 
 Improvements to Clang's diagnostics
 ^^^
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131892: [Sema] fix false -Wcomma being emitted from void returning functions

2022-08-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:74
   number of arguments cause an assertion fault.
+- Fix `#57151 `_.
+  ``-Wcomma`` is emitted for void returning functions.

Do we need an NFC commit to unify the format of issues mentioned here? (Maybe 
it can be scheduled for a later release). The different ways of citing issues 
here can be confusing.  `Issue ` `# xxx` in this context.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131892

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


[PATCH] D131892: [Sema] fix false -Wcomma being emitted from void returning functions

2022-08-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452767.
inclyc added a comment.

Address comments.

Thanks a lot for your suggestion, I noticed that the regression test tested both
C and C++, so I split the test mentioned in the comment into two parts.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131892

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/warn-comma-operator.cpp

Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,27 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void void_function_comma(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
+typedef void Void;
+Void typedef_func();
+
+void whatever() {
+  // We don't get confused about type aliases.
+  typedef_func(), int_func();
+  // Even function pointers don't confuse us.
+  void (*fp)() = void_func;
+  fp(), int_func();
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
@@ -296,4 +317,23 @@
   (void)T{}, 0;
   static_cast(T{}), 0;
 }
+
+namespace {
+
+// issue #57151
+
+struct S {
+  void mem() {}
+};
+
+void whatever() {
+  struct S s;
+  // Member function calls also work as expected.
+  s.mem(), int_func();
+  // As do lambda calls.
+  []() { return; }(), int_func();
+}
+
+} // namespace
+
 #endif  // ifdef __cplusplus
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returns void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,8 @@
 }
   }
 
+  if (const auto *CE = dyn_cast(E))
+return CE->getCallReturnType(Context)->isVoidType();
   return false;
 }
 
@@ -14014,7 +14018,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -71,6 +71,8 @@
 - Fix `#57008 `_ - Builtin
   C++ language extension type traits instantiated by a template with unexpected
   number of arguments cause an assertion fault.
+- Fix `#57151 `_.
+  ``-Wcomma`` is emitted for void returning functions.
 
 Improvements to Clang's diagnostics
 ^^^
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131892: [Sema] fix false -Wcomma being emited from void returning functions

2022-08-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452692.
inclyc added a comment.

typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131892

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/warn-comma-operator.cpp


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning 
type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : 
LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returns void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14019,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returns void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14019,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131892: [Sema] fix false -Wcomma being emited from void returning functions

2022-08-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452691.
inclyc added a comment.

Sync comments of function `IgnoreCommaOperand`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131892

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/warn-comma-operator.cpp


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning 
type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : 
LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returins void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14019,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13957,8 +13957,10 @@
   return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType();
 }
 
-// Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+// Scenarios to ignore if expression E is:
+// 1. an explicit cast expression into void
+// 2. a function call expression that returins void
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13975,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14019,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131892: [Sema] fix false -Wcomma being emited from void returning functions

2022-08-15 Thread YingChi Long via Phabricator via cfe-commits
inclyc created this revision.
Herald added a project: All.
inclyc updated this revision to Diff 452665.
inclyc added a comment.
inclyc added reviewers: aaron.ballman, rtrieu.
inclyc published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

comments


Fixes https://github.com/llvm/llvm-project/issues/57151


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131892

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/warn-comma-operator.cpp


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning 
type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13958,7 +13958,7 @@
 }
 
 // Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13973,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14017,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);


Index: clang/test/SemaCXX/warn-comma-operator.cpp
===
--- clang/test/SemaCXX/warn-comma-operator.cpp
+++ clang/test/SemaCXX/warn-comma-operator.cpp
@@ -140,6 +140,16 @@
   // CHECK: fix-it:{{.*}}:{[[@LINE-8]]:46-[[@LINE-8]]:46}:")"
 }
 
+
+void void_func();
+int int_func() { return 0; }
+
+void buggy(){
+  void_func(), int_func(); // expected no -Wcomma because of the returning type `void` 
+  // Reported by https://github.com/llvm/llvm-project/issues/57151
+  // Descriptions about -Wcomma: https://reviews.llvm.org/D3976
+}
+
 #ifdef __cplusplus
 class S2 {
 public:
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13958,7 +13958,7 @@
 }
 
 // Only ignore explicit casts to void.
-static bool IgnoreCommaOperand(const Expr *E) {
+static bool IgnoreCommaOperand(const Expr *E, const ASTContext ) {
   E = E->IgnoreParens();
 
   if (const CastExpr *CE = dyn_cast(E)) {
@@ -13973,6 +13973,9 @@
 }
   }
 
+  if (const CallExpr *CE = dyn_cast(E))
+if (const Type *T = CE->getCallReturnType(Context).getTypePtrOrNull())
+  return T->isVoidType();
   return false;
 }
 
@@ -14014,7 +14017,7 @@
   }
 
   // Only allow some expressions on LHS to not warn.
-  if (IgnoreCommaOperand(LHS))
+  if (IgnoreCommaOperand(LHS, Context))
 return;
 
   Diag(Loc, diag::warn_comma_operator);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131866: [clang] fix frontend crash in auto type templates

2022-08-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452572.
inclyc added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131866

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/SemaCXX/sugared-auto.cpp


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,33 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // crashed here in #57142
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,33 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // crashed here in #57142
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131866: [clang] fix frontend crash in auto type templates

2022-08-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452571.
inclyc added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131866

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/SemaCXX/sugared-auto.cpp


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,39 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+struct true_type {
+  static const bool value = true;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // crashed here in #57142
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,39 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+struct true_type {
+  static const bool value = true;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // crashed here in #57142
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131866: [clang] fix frontend crash in auto type templates

2022-08-14 Thread YingChi Long via Phabricator via cfe-commits
inclyc updated this revision to Diff 452569.
inclyc added a comment.

update comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131866

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/SemaCXX/sugared-auto.cpp


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,39 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+struct true_type {
+  static const bool value = true;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // before this patch clang crashes 
here
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();


Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -41,3 +41,39 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace issue57142 {
+
+// Should not crash here
+// Reported by https://github.com/llvm/llvm-project/issues/57142
+
+
+// Only crashes if `tuple` is defined outside of the buggy namespace
+namespace outer {
+template  class tuple;
+} // namespace outer
+
+namespace {
+struct false_type {
+  static const bool value = false;
+};
+
+struct true_type {
+  static const bool value = true;
+};
+
+template class, typename>
+struct IsTemplateOf : false_type {};
+
+
+
+template class ATemplate>
+concept InitFrom = IsTemplateOf::value;
+
+
+static void buggy_func(
+const InitFrom auto& C // before this patch clang crashes here
+); 
+} // namespace
+
+} // namespace issue57142
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -5732,7 +5732,8 @@
 Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
 TypeConstraintConcept, CanonArgs, true);
 // Find the insert position again.
-AutoTypes.FindNodeOrInsertPos(ID, InsertPos);
+if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+  return QualType(AT, 0);
   }
 } else {
   Canon = DeducedType.getCanonicalType();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >