[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2023-12-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/76619

Fixes #76425

>From b26fa2acfd4974d1c09eef408b4d6c2dcbb16479 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Sun, 31 Dec 2023 00:32:01 +0800
Subject: [PATCH] [ASTMatchers] fix captureVars assertion failure on
 capturesVariables

Fixes #76425
---
 clang/include/clang/ASTMatchers/ASTMatchers.h   | 2 ++
 clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 82a26356c58f55..91c33e4b1163e6 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4817,6 +4817,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, 
internal::Matcher,
 /// capturesVar(hasName("x")) matches `x` and `x = 1`.
 AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher,
   InnerMatcher) {
+  if (!Node.capturesVariable())
+return false;
   auto *capturedVar = Node.getCapturedVar();
   return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
 }
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 8f0dd5602307c5..eb493f9c3050ac 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2308,6 +2308,8 @@ TEST_P(ASTMatchersTest, 
LambdaCaptureTest_BindsToCaptureOfVarDecl) {
   matches("int main() { int cc; auto f = [=](){ return cc; }; }", 
matcher));
   EXPECT_TRUE(
   matches("int main() { int cc; auto f = [&](){ return cc; }; }", 
matcher));
+  EXPECT_TRUE(matches(
+  "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
 }
 
 TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {

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


[clang] [clang][Parser] Pop scope prior VarDecl invalidating by invalid init (PR #77434)

2024-01-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/77434

Invalid (direct) initializer would invalid `VarDecl` so `InitializerScopeRAII` 
cannot restore scope stack balance.

As with other kind of initializer, `InitializerScopeRAII::pop()` is moved up 
before `Sema::ActOnInitializerError()` which invalidates the `VarDecl`, so 
scope can be balanced and current `DeclContext` can be restored.

Fixes #30908

>From 6934d23d9276a0a0997a31d206ffaaa146243db1 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Tue, 9 Jan 2024 16:40:23 +0800
Subject: [PATCH] [clang][Parser] Pop scope prior VarDecl invalidating by
 invalid direct Init

Invalid (direct) initializer would invalid VarDecl so InitializerScopeRAII
cannot restore scope stack balance.

As with other kind of initializer, InitializerScopeRAII::pop() is moved up
before Sema::ActOnInitializerError() which invalidates the VarDecl, so
scope can be balanced and current DeclContext can be restored.

Fixes #30908
---
 clang/lib/Parse/ParseDecl.cpp |  8 +--
 ...ope-balance-on-invalid-var-direct-init.cpp | 22 +++
 2 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 
clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init.cpp

diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index b60ae293ef8c20..ed684c5d57b1ee 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2661,7 +2661,12 @@ Decl 
*Parser::ParseDeclarationAfterDeclaratorAndAttributes(
   // ProduceConstructorSignatureHelp only on VarDecls.
   ExpressionStarts = SetPreferredType;
 }
-if (ParseExpressionList(Exprs, ExpressionStarts)) {
+
+bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
+
+InitScope.pop();
+
+if (SawError) {
   if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) 
{
 Actions.ProduceConstructorSignatureHelp(
 ThisVarDecl->getType()->getCanonicalTypeInternal(),
@@ -2674,7 +2679,6 @@ Decl 
*Parser::ParseDeclarationAfterDeclaratorAndAttributes(
 } else {
   // Match the ')'.
   T.consumeClose();
-  InitScope.pop();
 
   ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
   T.getCloseLocation(),
diff --git 
a/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init.cpp 
b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init.cpp
new file mode 100644
index 00..02200ce4f34a75
--- /dev/null
+++ b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include  // expected-error {{file not found}}
+
+class S {};
+
+template 
+class E {
+public:
+  E(S* scope) {}
+  S &getS();
+};
+
+class Z {
+ private:
+  static E e;
+  static S& s();
+};
+
+E Z::e(&__UNKNOWN_ID__);
+
+S& Z::s() { return Z::e.getS(); }

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


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-01-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/76619

>From 50c0ccd9a28896a1f8f673446054abd6f18703a9 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Sun, 31 Dec 2023 00:32:01 +0800
Subject: [PATCH] [ASTMatchers] fix captureVars assertion failure on
 capturesVariables

Matcher 'capturesVar' should check for capturesVariables() before
calling getCaptureVar() since it asserts this LambdaCapture does capture
a variable.

Fixes #76425
---
 clang/include/clang/ASTMatchers/ASTMatchers.h   | 2 ++
 clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 82a26356c58f556..91c33e4b1163e6d 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4817,6 +4817,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, 
internal::Matcher,
 /// capturesVar(hasName("x")) matches `x` and `x = 1`.
 AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher,
   InnerMatcher) {
+  if (!Node.capturesVariable())
+return false;
   auto *capturedVar = Node.getCapturedVar();
   return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
 }
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 8f0dd5602307c53..eb493f9c3050acb 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2308,6 +2308,8 @@ TEST_P(ASTMatchersTest, 
LambdaCaptureTest_BindsToCaptureOfVarDecl) {
   matches("int main() { int cc; auto f = [=](){ return cc; }; }", 
matcher));
   EXPECT_TRUE(
   matches("int main() { int cc; auto f = [&](){ return cc; }; }", 
matcher));
+  EXPECT_TRUE(matches(
+  "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
 }
 
 TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {

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


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-01-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/76619
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-01-09 Thread Ding Fei via cfe-commits

danix800 wrote:

> Thank you for the fix, can you add more details to your summary. The summary 
> is what usually goes into the git log. We would like those to be as 
> descriptive as possible to avoid having to do extra digging to understand the 
> change at a high level.

Thanks for reminding. Summary updated, please take another look.

https://github.com/llvm/llvm-project/pull/76619
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Parser] Pop scope prior VarDecl invalidating by invalid init (PR #77434)

2024-01-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/77434

>From 2f9e45458d21952f9e81cd54297f538d1d04b9f9 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Tue, 9 Jan 2024 16:40:23 +0800
Subject: [PATCH] [clang][Parser] Pop scope prior VarDecl invalidating by
 invalid direct Init

Invalid (direct) initializer would invalid VarDecl so InitializerScopeRAII
cannot restore scope stack balance.

As with other kind of initializers, InitializerScopeRAII::pop() is moved up
before Sema::ActOnInitializerError() which invalidates the VarDecl, so
scope can be balanced and current DeclContext can be restored.

Fixes #30908
---
 clang/docs/ReleaseNotes.rst   |  3 +++
 clang/lib/Parse/ParseDecl.cpp |  8 +--
 ...e-balance-on-invalid-var-direct-init-1.cpp | 20 +
 ...e-balance-on-invalid-var-direct-init-2.cpp | 22 +++
 4 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 
clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp
 create mode 100644 
clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ddeb1186d65ac8..46f4b82b89e488 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -702,6 +702,9 @@ Bug Fixes in This Version
 - Fix assertion failure when initializing union containing struct with
   flexible array member using empty initializer list.
   Fixes (`#77085 `_)
+- Fix assertion crash due to failed scope restoring caused by too-early VarDecl
+  invalidation by invalid initializer Expr.
+  Fixes (`#30908 `_)
 
 
 Bug Fixes to Compiler Builtins
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index b60ae293ef8c20..ed684c5d57b1ee 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2661,7 +2661,12 @@ Decl 
*Parser::ParseDeclarationAfterDeclaratorAndAttributes(
   // ProduceConstructorSignatureHelp only on VarDecls.
   ExpressionStarts = SetPreferredType;
 }
-if (ParseExpressionList(Exprs, ExpressionStarts)) {
+
+bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
+
+InitScope.pop();
+
+if (SawError) {
   if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) 
{
 Actions.ProduceConstructorSignatureHelp(
 ThisVarDecl->getType()->getCanonicalTypeInternal(),
@@ -2674,7 +2679,6 @@ Decl 
*Parser::ParseDeclarationAfterDeclaratorAndAttributes(
 } else {
   // Match the ')'.
   T.consumeClose();
-  InitScope.pop();
 
   ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
   T.getCloseLocation(),
diff --git 
a/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp 
b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp
new file mode 100644
index 00..1a692fe8ff1e72
--- /dev/null
+++ b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-1.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -ferror-limit 2 -fsyntax-only -verify %s
+
+// expected-error@* {{too many errors emitted}}
+
+namespace llvm {
+namespace Hexagon {}
+}
+void set() {
+  Hexagon::NoRegister;
+  // expected-error@-1 {{use of undeclared identifier}}
+  // expected-note@-5 {{declared here}}
+  // expected-error@-3 {{no member named 'NoRegister' in namespace}}
+}
+template  struct pair { pair(int, int); };
+struct HexagonMCChecker {
+  static pair Unconditional;
+  void checkRegisters();
+};
+pair HexagonMCChecker::Unconditional(Hexagon::NoRegister, 0);
+void HexagonMCChecker::checkRegisters() {}
diff --git 
a/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp 
b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp
new file mode 100644
index 00..02200ce4f34a75
--- /dev/null
+++ b/clang/test/Parser/gh30908-scope-balance-on-invalid-var-direct-init-2.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include  // expected-error {{file not found}}
+
+class S {};
+
+template 
+class E {
+public:
+  E(S* scope) {}
+  S &getS();
+};
+
+class Z {
+ private:
+  static E e;
+  static S& s();
+};
+
+E Z::e(&__UNKNOWN_ID__);
+
+S& Z::s() { return Z::e.getS(); }

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


[clang] [clang][Parser] Pop scope prior VarDecl invalidating by invalid init (PR #77434)

2024-01-09 Thread Ding Fei via cfe-commits

danix800 wrote:

> This makes sense to me but I would like @cor3ntin to review as well.
> 
> This needs a release note.

Release note is added.

> 
> I see that there was two test cases. Do you think it is worth it to add the 
> second test case as well?

The original testcase from #30908 is added too for completeness.

Please take another look @shafik @cor3ntin 

https://github.com/llvm/llvm-project/pull/77434
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Parser] Pop scope prior VarDecl invalidating by invalid init (PR #77434)

2024-01-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 closed 
https://github.com/llvm/llvm-project/pull/77434
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] fix assert fail due to offset overflow (PR #79084)

2024-01-29 Thread Ding Fei via cfe-commits


@@ -9896,9 +9903,13 @@ Expected ASTImporter::Import(FileID FromID, bool 
IsBuiltin) {
 // FIXME: The filename may be a virtual name that does probably not
 // point to a valid file and we get no Entry here. In this case try 
with
 // the memory buffer below.
-if (Entry)
+if (Entry) {
+  if (isBufferSizeOverflow(ToSM, Entry->getSize()))
+return llvm::make_error(
+ASTImportError::UnsupportedConstruct);

danix800 wrote:

`ASTImportError::Unknown` would crash CTU module too, 
`ASTImportError::UnsupportedConstruct` might be deliberately chosen so the 
analysis could continue in this case.

https://github.com/llvm/llvm-project/pull/79084
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] fix assert fail due to offset overflow (PR #79084)

2024-01-29 Thread Ding Fei via cfe-commits


@@ -9896,9 +9903,13 @@ Expected ASTImporter::Import(FileID FromID, bool 
IsBuiltin) {
 // FIXME: The filename may be a virtual name that does probably not
 // point to a valid file and we get no Entry here. In this case try 
with
 // the memory buffer below.

danix800 wrote:

Invalid file could exist in real case (causes no Entry) while `SourceLocation` 
overflow is normally caused by cumulative effect of multiple (large enough) 
files imported so I think these two are not connected.

https://github.com/llvm/llvm-project/pull/79084
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] fix crash & improve comparing on GenericSelectionExpr (PR #67458)

2023-09-26 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/67458

1. fix crash on 'default' assoc which has no TypeSourceInfo (nullptr);
2. improve equivalency comparison on control expr & associated exprs.

>From e411aa494c09a8f412ee90f302504cd469ef1283 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 27 Sep 2023 01:01:06 +0800
Subject: [PATCH] fix crash & improve comparing on GenericSelectionExpr

1. fix crash on 'default' assoc which has no TypeSourceInfo (nullptr);
2. improve equivalency comparison on control expr & associated exprs.
---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 20 +
 .../AST/StructuralEquivalenceTest.cpp | 22 +++
 2 files changed, 42 insertions(+)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 5b98d14dd3d9104..d9b2f045552d52c 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -247,6 +247,20 @@ class StmtComparer {
 
   bool IsStmtEquivalent(const GenericSelectionExpr *E1,
 const GenericSelectionExpr *E2) {
+if (!IsStructurallyEquivalent(Context,
+  const_cast(E1->getControllingExpr()),
+  const_cast(E2->getControllingExpr(
+  return false;
+
+for (auto Pair : zip_longest(E1->getAssocExprs(), E2->getAssocExprs())) {
+  std::optional Child1 = std::get<0>(Pair);
+  std::optional Child2 = std::get<1>(Pair);
+  if (!Child1 || !Child2)
+return false;
+  if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
+return false;
+}
+
 for (auto Pair : zip_longest(E1->getAssocTypeSourceInfos(),
  E2->getAssocTypeSourceInfos())) {
   std::optional Child1 = std::get<0>(Pair);
@@ -255,6 +269,12 @@ class StmtComparer {
   if (!Child1 || !Child2)
 return false;
 
+  if (!(*Child1) != !(*Child2))
+return false;
+
+  if (!(*Child1))
+continue;
+
   if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
 (*Child2)->getType()))
 return false;
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 44d950cfe758f14..35c1385e73fb389 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -2091,6 +2091,28 @@ TEST_F(StructuralEquivalenceStmtTest, 
GenericSelectionExprOrderDiffers) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprControlDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(1u, unsigned int: 0, float: 1)", 
Lang_C99,
+genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprAssocExprDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(0u, unsigned int: 1u, float: 1)", 
Lang_C99,
+genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest,
+   GenericSelectionExprDefaultNoTypeSourceInfo) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, default: 1)",
+"_Generic(0u, unsigned int: 0, default: 1)",
+Lang_C99, genericSelectionExpr());
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) 
{
   auto t = makeStmts(
   R"(

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


[clang] fix crash & improve comparing on GenericSelectionExpr (PR #67458)

2023-09-26 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/67458

>From 35bdb04db16c79d68dbe6522d01a0a08b2840d69 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 27 Sep 2023 01:01:06 +0800
Subject: [PATCH] [StructuralEquivalence] fix crash & improve comparing on
 GenericSelectionExpr

1. fix crash on 'default' assoc which has no TypeSourceInfo (nullptr);
2. improve equivalency comparison on control expr & associated exprs.
---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 20 +
 .../AST/StructuralEquivalenceTest.cpp | 22 +++
 2 files changed, 42 insertions(+)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 5b98d14dd3d9104..d9b2f045552d52c 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -247,6 +247,20 @@ class StmtComparer {
 
   bool IsStmtEquivalent(const GenericSelectionExpr *E1,
 const GenericSelectionExpr *E2) {
+if (!IsStructurallyEquivalent(Context,
+  const_cast(E1->getControllingExpr()),
+  const_cast(E2->getControllingExpr(
+  return false;
+
+for (auto Pair : zip_longest(E1->getAssocExprs(), E2->getAssocExprs())) {
+  std::optional Child1 = std::get<0>(Pair);
+  std::optional Child2 = std::get<1>(Pair);
+  if (!Child1 || !Child2)
+return false;
+  if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
+return false;
+}
+
 for (auto Pair : zip_longest(E1->getAssocTypeSourceInfos(),
  E2->getAssocTypeSourceInfos())) {
   std::optional Child1 = std::get<0>(Pair);
@@ -255,6 +269,12 @@ class StmtComparer {
   if (!Child1 || !Child2)
 return false;
 
+  if (!(*Child1) != !(*Child2))
+return false;
+
+  if (!(*Child1))
+continue;
+
   if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
 (*Child2)->getType()))
 return false;
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 44d950cfe758f14..35c1385e73fb389 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -2091,6 +2091,28 @@ TEST_F(StructuralEquivalenceStmtTest, 
GenericSelectionExprOrderDiffers) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprControlDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(1u, unsigned int: 0, float: 1)", 
Lang_C99,
+genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprAssocExprDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(0u, unsigned int: 1u, float: 1)", 
Lang_C99,
+genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest,
+   GenericSelectionExprDefaultNoTypeSourceInfo) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, default: 1)",
+"_Generic(0u, unsigned int: 0, default: 1)",
+Lang_C99, genericSelectionExpr());
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) 
{
   auto t = makeStmts(
   R"(

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


[clang] [StructuralEquivalence] fix crash & improve comparing on GenericSelectionExpr (PR #67458)

2023-09-26 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/67458
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [StructuralEquivalence] fix crash & improve comparing on GenericSelectionExpr (PR #67458)

2023-09-26 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/67458

>From 9bf05ae5cd69fb99e1978cdc766f8392f92626c3 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 27 Sep 2023 01:01:06 +0800
Subject: [PATCH] [StructuralEquivalence] fix crash & improve comparing on
 GenericSelectionExpr

1. fix crash on 'default' assoc which has no TypeSourceInfo (nullptr);
2. improve equivalency comparison on control expr & associated exprs.
---
 clang/lib/AST/ASTStructuralEquivalence.cpp| 20 +
 .../AST/StructuralEquivalenceTest.cpp | 22 +++
 2 files changed, 42 insertions(+)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 5b98d14dd3d9104..d9b2f045552d52c 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -247,6 +247,20 @@ class StmtComparer {
 
   bool IsStmtEquivalent(const GenericSelectionExpr *E1,
 const GenericSelectionExpr *E2) {
+if (!IsStructurallyEquivalent(Context,
+  const_cast(E1->getControllingExpr()),
+  const_cast(E2->getControllingExpr(
+  return false;
+
+for (auto Pair : zip_longest(E1->getAssocExprs(), E2->getAssocExprs())) {
+  std::optional Child1 = std::get<0>(Pair);
+  std::optional Child2 = std::get<1>(Pair);
+  if (!Child1 || !Child2)
+return false;
+  if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
+return false;
+}
+
 for (auto Pair : zip_longest(E1->getAssocTypeSourceInfos(),
  E2->getAssocTypeSourceInfos())) {
   std::optional Child1 = std::get<0>(Pair);
@@ -255,6 +269,12 @@ class StmtComparer {
   if (!Child1 || !Child2)
 return false;
 
+  if (!(*Child1) != !(*Child2))
+return false;
+
+  if (!(*Child1))
+continue;
+
   if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
 (*Child2)->getType()))
 return false;
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 44d950cfe758f14..639cefbc0e99a18 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -2091,6 +2091,28 @@ TEST_F(StructuralEquivalenceStmtTest, 
GenericSelectionExprOrderDiffers) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprControlDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(1u, unsigned int: 0, float: 1)", 
Lang_C99,
+genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprAssocExprDiffers) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+"_Generic(0u, unsigned int: 1u, float: 1)",
+Lang_C99, genericSelectionExpr());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest,
+   GenericSelectionExprDefaultNoTypeSourceInfo) {
+  auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, default: 1)",
+"_Generic(0u, unsigned int: 0, default: 1)",
+Lang_C99, genericSelectionExpr());
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) 
{
   auto t = makeStmts(
   R"(

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


[clang] [clang][ASTImporter] Fix crash when template class static member imported to other translation unit. (PR #68774)

2023-10-12 Thread Ding Fei via cfe-commits

danix800 wrote:

Caused by missing `MemberSpecializationInfo` when importing so moving testcase 
into `ASTImporterTest` as unittest would be better.

https://github.com/llvm/llvm-project/pull/68774
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448:

>From 235f39a6a5137e53239105727798d4540e5dd563 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH 1/2] [analyzer] Reduce constraint on modulo with small
 concrete range

---
 .../Core/RangeConstraintManager.cpp   | 48 +++
 clang/test/Analysis/constraint-assignor.c | 60 +++
 2 files changed, 108 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c8..9bda29c87f3c0f1 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/test/Analysis/constraint-assignor.c 
b/clang/test/Analysis/constraint-assignor.c
index 8210e576c98bd21..150fe20c9f37a0a 100644
--- a/clang/test/Analysis/constraint-assignor.c
+++ b/clang/test/Analysis/constraint-assignor.c
@@ -5,6 +5,7 @@
 
 void clang_analyzer_warnIfReached(void);
 void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
 
 void rem_constant_rhs_ne_zero(int x, int y) {
   if (x % 3 == 0) // x % 3 != 0 -> x != 0
@@ -82,3 +83,62 @@ void remainder_with_adjustment_of_composit_lhs(int x, int y) 
{
   clang_analyzer_eval(x + y != -1);// expected-warning{{TRUE}}
   (void)(x * y); // keep the constraints alive.
 }
+
+void remainder_infeasible(int x, int y) {
+  if (x <= 2 || x >= 5)
+return;
+  if (x % 5 != 0)
+return;
+  clang_analyzer_warnIfReached(); // no-warning
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range_unsigned(unsigned x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range(int x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_range_spans_zero(int x) {
+  if (x <= -2 || x > 2)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{0 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void rem

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 unlabeled 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 ready_for_review 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 review_requested 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 review_requested 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448:

>From 235f39a6a5137e53239105727798d4540e5dd563 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH 1/2] [analyzer] Reduce constraint on modulo with small
 concrete range

---
 .../Core/RangeConstraintManager.cpp   | 48 +++
 clang/test/Analysis/constraint-assignor.c | 60 +++
 2 files changed, 108 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c8..9bda29c87f3c0f1 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/test/Analysis/constraint-assignor.c 
b/clang/test/Analysis/constraint-assignor.c
index 8210e576c98bd21..150fe20c9f37a0a 100644
--- a/clang/test/Analysis/constraint-assignor.c
+++ b/clang/test/Analysis/constraint-assignor.c
@@ -5,6 +5,7 @@
 
 void clang_analyzer_warnIfReached(void);
 void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
 
 void rem_constant_rhs_ne_zero(int x, int y) {
   if (x % 3 == 0) // x % 3 != 0 -> x != 0
@@ -82,3 +83,62 @@ void remainder_with_adjustment_of_composit_lhs(int x, int y) 
{
   clang_analyzer_eval(x + y != -1);// expected-warning{{TRUE}}
   (void)(x * y); // keep the constraints alive.
 }
+
+void remainder_infeasible(int x, int y) {
+  if (x <= 2 || x >= 5)
+return;
+  if (x % 5 != 0)
+return;
+  clang_analyzer_warnIfReached(); // no-warning
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range_unsigned(unsigned x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range(int x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_range_spans_zero(int x) {
+  if (x <= -2 || x > 2)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{0 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void rem

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 unlabeled 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 converted_to_draft 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448:

>From 235f39a6a5137e53239105727798d4540e5dd563 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH 1/3] [analyzer] Reduce constraint on modulo with small
 concrete range

---
 .../Core/RangeConstraintManager.cpp   | 48 +++
 clang/test/Analysis/constraint-assignor.c | 60 +++
 2 files changed, 108 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c8..9bda29c87f3c0f1 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/test/Analysis/constraint-assignor.c 
b/clang/test/Analysis/constraint-assignor.c
index 8210e576c98bd21..150fe20c9f37a0a 100644
--- a/clang/test/Analysis/constraint-assignor.c
+++ b/clang/test/Analysis/constraint-assignor.c
@@ -5,6 +5,7 @@
 
 void clang_analyzer_warnIfReached(void);
 void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
 
 void rem_constant_rhs_ne_zero(int x, int y) {
   if (x % 3 == 0) // x % 3 != 0 -> x != 0
@@ -82,3 +83,62 @@ void remainder_with_adjustment_of_composit_lhs(int x, int y) 
{
   clang_analyzer_eval(x + y != -1);// expected-warning{{TRUE}}
   (void)(x * y); // keep the constraints alive.
 }
+
+void remainder_infeasible(int x, int y) {
+  if (x <= 2 || x >= 5)
+return;
+  if (x % 5 != 0)
+return;
+  clang_analyzer_warnIfReached(); // no-warning
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range_unsigned(unsigned x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range(int x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_range_spans_zero(int x) {
+  if (x <= -2 || x > 2)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{0 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void rem

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 unlabeled 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448:

>From 501595caf608aaeb8253235c32de5dd3ef4d3439 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH 1/3] [analyzer] Reduce constraint on modulo with small
 concrete range

---
 .../Core/RangeConstraintManager.cpp   | 48 +++
 clang/test/Analysis/constraint-assignor.c | 60 +++
 2 files changed, 108 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c8..9bda29c87f3c0f1 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/test/Analysis/constraint-assignor.c 
b/clang/test/Analysis/constraint-assignor.c
index 8210e576c98bd21..150fe20c9f37a0a 100644
--- a/clang/test/Analysis/constraint-assignor.c
+++ b/clang/test/Analysis/constraint-assignor.c
@@ -5,6 +5,7 @@
 
 void clang_analyzer_warnIfReached(void);
 void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
 
 void rem_constant_rhs_ne_zero(int x, int y) {
   if (x % 3 == 0) // x % 3 != 0 -> x != 0
@@ -82,3 +83,62 @@ void remainder_with_adjustment_of_composit_lhs(int x, int y) 
{
   clang_analyzer_eval(x + y != -1);// expected-warning{{TRUE}}
   (void)(x * y); // keep the constraints alive.
 }
+
+void remainder_infeasible(int x, int y) {
+  if (x <= 2 || x >= 5)
+return;
+  if (x % 5 != 0)
+return;
+  clang_analyzer_warnIfReached(); // no-warning
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range_unsigned(unsigned x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range(int x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_range_spans_zero(int x) {
+  if (x <= -2 || x > 2)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{0 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void rem

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 unlabeled 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 review_requested 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 ready_for_review 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-14 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/66463

NonLoc symbolic SVal to Loc casts are not supported except for 
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can go through 
nonloc::ConcreteInt->loc::ConcreteInt path. For example:

```c
  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }
```
If simplified, `t2` is 0, resulting `p` is nullptr, otherwise `p` is unknown.

Fixes #62232

>From e171f8ea4d0fea12dadad6b0ecaffba42ff6ba85 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 15 Sep 2023 14:01:26 +0800
Subject: [PATCH] [analyzer] Simplify SVal for simple NonLoc->Loc casts

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |  3 +-
 ...solver-sym-simplification-lvalue-bitcast.c | 31 +++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 
clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());
diff --git a/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c 
b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
new file mode 100644
index 000..db8b1456527e523
--- /dev/null
+++ b/clang/test/Analysis/solver-sym-simplification-lvalue-bitcast.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

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


[clang] [clang] fix lack comparison of declRefExpr in ASTStructuralEquivalence (PR #66041)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -218,6 +218,8 @@ Bug Fixes in This Version
   (`#65156 `_)
 - Clang no longer considers the loss of ``__unaligned`` qualifier from objects 
as
   an invalid conversion during method function overload resolution.
+- Fix lack of comparison of declRefExpr in ASTStructuralEquivalence
+  (`#66047 `_`)

danix800 wrote:

```suggestion
  (`#66047 `_)
```

https://github.com/llvm/llvm-project/pull/66041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] fix lack comparison of declRefExpr in ASTStructuralEquivalence (PR #66041)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -2320,5 +2320,14 @@ TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceStmtTest, DeclRefENoEq) {

danix800 wrote:

```suggestion
TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
```

https://github.com/llvm/llvm-project/pull/66041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);

danix800 wrote:

Bound value might not be used at all, so I think lazy simplification would be 
better.

https://github.com/llvm/llvm-project/pull/66463
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;

danix800 wrote:

I'll move this into `symbol-simplification-nonloc-loc.cpp` which already 
restrict that target to be `x86_64`.

https://github.com/llvm/llvm-project/pull/66463
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -verify
+
+void clang_analyzer_eval(int);
+
+void test_simplified_before_cast_add(long long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

danix800 wrote:

Moved this into `symbol-simplification-nonloc-loc.cpp`.

https://github.com/llvm/llvm-project/pull/66463
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/66463

>From d48b57387e3dc1c2f3fdeae00fe1596b3466638d Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 15 Sep 2023 14:01:26 +0800
Subject: [PATCH] [analyzer] Simplify SVal for simple NonLoc->Loc casts

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |  3 ++-
 .../symbol-simplification-nonloc-loc.cpp  | 26 +++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());
diff --git a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp 
b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
index 485f68d9a5acfba..619fda824cb70b5 100644
--- a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
+++ b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
 // RUN:-triple x86_64-pc-linux-gnu -verify
 
+void clang_analyzer_eval(int);
+
 #define BINOP(OP) [](auto x, auto y) { return x OP y; }
 
 template 
@@ -73,3 +75,27 @@ void zoo1backwards() {
   *(0 + p) = nullptr;  // warn
   **(0 + p) = 'a'; // no-warning: this should be unreachable
 }
+
+void test_simplified_before_cast_add(long t1) {
+  long long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long t1) {
+  long long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long t1) {
+  long long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66498)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/66498

NonLoc symbolic SVal to Loc casts are not supported except for 
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can go through 
nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p' is unknown.

Fixes #62232

>From 0b776deb2bbd4d03325b02680eb99c788d3bc37d Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 15 Sep 2023 14:01:26 +0800
Subject: [PATCH] [analyzer] Simplify SVal for simple NonLoc->Loc casts

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp |  3 +-
 .../symbol-simplification-nonloc-loc.cpp  | 28 ++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());
diff --git a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp 
b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
index 485f68d9a5acfba..6cfe8da971429c3 100644
--- a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
+++ b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s \
 // RUN:-triple x86_64-pc-linux-gnu -verify
 
+void clang_analyzer_eval(int);
+
 #define BINOP(OP) [](auto x, auto y) { return x OP y; }
 
 template 
@@ -73,3 +75,27 @@ void zoo1backwards() {
   *(0 + p) = nullptr;  // warn
   **(0 + p) = 'a'; // no-warning: this should be unreachable
 }
+
+void test_simplified_before_cast_add(long t1) {
+  long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long t1) {
+  long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long t1) {
+  long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

Fixed and resubmited #66498

https://github.com/llvm/llvm-project/pull/66463
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66498)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/66498
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][AST] fix lack comparison of declRefExpr in ASTStructuralEquivalence (PR #66041)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

LGTM! If no further comment I'll merge this in a day or two.

https://github.com/llvm/llvm-project/pull/66041
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

`auto-merge` might be disabled probably. I can't find the button mentioned 
[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request).

https://github.com/llvm/llvm-project/pull/66463
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448

>From 111de0e99482cf8c8c206286bb9a4f40149992c6 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH] [analyzer] Improve constraint inferring on concrete div/mod

1. Reduce constraint on modulo with small concrete range when assigned;
2. Improve constraint inferring on modulo over concrete value;
3. Improve constraint inferring on division over concrete value.

Fixes #54377
---
 .../Core/RangeConstraintManager.cpp   | 157 ++
 clang/test/Analysis/constraint-assignor.c | 108 
 clang/test/Analysis/constraint-infer-div.c|  64 +++
 clang/test/Analysis/constraint-infer-mod.c|  98 +++
 4 files changed, 427 insertions(+)
 create mode 100644 clang/test/Analysis/constraint-infer-div.c
 create mode 100644 clang/test/Analysis/constraint-infer-mod.c

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c8..15f5246335d9d26 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -1338,6 +1338,9 @@ class SymbolicRangeInferrer
   RangeSet VisitBinaryOperator(RangeSet LHS, BinaryOperator::Opcode Op,
RangeSet RHS, QualType T);
 
+  RangeSet handleConcreteModulo(Range LHS, llvm::APSInt Modulo, QualType T);
+  RangeSet handleRangeModulo(Range LHS, Range RHS, QualType T);
+
   
//===--===//
   // Ranges and operators
   
//===--===//
@@ -1771,6 +1774,14 @@ template <>
 RangeSet SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
 Range RHS,
 QualType T) {
+  if (const llvm::APSInt *ModOrNull = RHS.getConcreteValue())
+return handleConcreteModulo(LHS, *ModOrNull, T);
+
+  return handleRangeModulo(LHS, RHS, T);
+}
+
+RangeSet SymbolicRangeInferrer::handleRangeModulo(Range LHS, Range RHS,
+  QualType T) {
   llvm::APSInt Zero = ValueFactory.getAPSIntType(T).getZeroValue();
 
   Range ConservativeRange = getSymmetricalRange(RHS, T);
@@ -1824,6 +1835,101 @@ RangeSet 
SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
   return {RangeFactory, ValueFactory.getValue(Min), 
ValueFactory.getValue(Max)};
 }
 
+RangeSet SymbolicRangeInferrer::handleConcreteModulo(Range LHS,
+ llvm::APSInt Modulo,
+ QualType T) {
+  APSIntType ResultType = ValueFactory.getAPSIntType(T);
+  llvm::APSInt Zero = ResultType.getZeroValue();
+  llvm::APSInt One = ResultType.getValue(1);
+
+  if (Modulo == Zero)
+return RangeFactory.getEmptySet();
+
+  // Quick path, this also avoids unary '-' overflow on MinValue modulo.
+  if (Modulo == ValueFactory.getMinValue(T) ||
+  Modulo == ValueFactory.getMaxValue(T))
+return RangeFactory.getRangeSet(LHS);
+
+  // Normalize to positive modulo since a % N == a % -N
+  if (Modulo < 0)
+Modulo = -Modulo;
+
+  auto ComputeModuloN = [&](llvm::APSInt From, llvm::APSInt To,
+llvm::APSInt N) -> RangeSet {
+assert(N > Zero && "Positive N expected!");
+bool NonNegative = From >= Zero;
+assert(NonNegative == (To >= Zero) && "Signedness mismatch!");
+
+if (From > To)
+  return RangeFactory.getEmptySet();
+
+llvm::APSInt N1 = N - One;
+
+// spans [0, N - 1] if NonNegative or [-(N - 1), 0] otherwise.
+if ((To - From) / N > Zero)
+  return {RangeFactory, ValueFactory.getValue(NonNegative ? Zero : -N1),
+  ValueFactory.getValue(NonNegative ? N1 : Zero)};
+
+llvm::APSInt Min = From % N;
+llvm::APSInt Max = To % N;
+
+if (Min < Max) // [Min, Max]
+  return {RangeFactory, ValueFactory.getValue(Min),
+  ValueFactory.getValue(Max)};
+
+// [0, Max] U [Min, N - 1] if NonNegative, or
+// [-(N - 1), Max] U [Min, 0] otherwise.
+const llvm::APSInt &Min1 = ValueFactory.getValue(NonNegative ? Zero : -N1);
+const llvm::APSInt &Max1 = ValueFactory.getValue(Max);
+RangeSet RS1{RangeFactory, Min1, Max1};
+
+const llvm::APSInt &Min2 = ValueFactory.getValue(Min);
+const llvm::APSInt &Max2 = ValueFactory.getValue(NonNegative ? N1 : Zero);
+RangeSet RS2{RangeFactory, Min2, Max2};
+
+return RangeFactory.unite(RS1, RS2);
+  };
+
+  if (!LHS.Includes(Zero))
+return ComputeModuloN(LHS.From(), LHS.To(), Modulo);
+
+  // split over [From, -1] U [0, To] for easy handling.
+  return RangeFactory.unite(ComputeModuloN(LHS.From(), -One, Modulo),
+ComputeModuloN(Zero

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Improve constraint inferring on concrete div/mod (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Improve constraint inferring on concrete div/mod (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -1824,6 +1835,94 @@ RangeSet 
SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
   return {RangeFactory, ValueFactory.getValue(Min), 
ValueFactory.getValue(Max)};
 }
 
+RangeSet SymbolicRangeInferrer::handleConcreteModulo(Range LHS,
+ llvm::APSInt Modulo,
+ QualType T) {
+  APSIntType ResultType = ValueFactory.getAPSIntType(T);
+  llvm::APSInt Zero = ResultType.getZeroValue();
+  llvm::APSInt One = ResultType.getValue(1);
+
+  if (Modulo == Zero)
+return RangeFactory.getEmptySet();
+  if (Modulo < 0)
+Modulo = -Modulo;

danix800 wrote:

Actually `X % Y == X % -Y`, not `X % Y == -X % Y` or `X % Y == -X % -Y`. Sign 
of Y is not significant.

https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Improve constraint inferring on concrete div/mod (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits


@@ -1824,6 +1835,94 @@ RangeSet 
SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
   return {RangeFactory, ValueFactory.getValue(Min), 
ValueFactory.getValue(Max)};
 }
 
+RangeSet SymbolicRangeInferrer::handleConcreteModulo(Range LHS,
+ llvm::APSInt Modulo,
+ QualType T) {
+  APSIntType ResultType = ValueFactory.getAPSIntType(T);
+  llvm::APSInt Zero = ResultType.getZeroValue();
+  llvm::APSInt One = ResultType.getValue(1);
+
+  if (Modulo == Zero)
+return RangeFactory.getEmptySet();
+  if (Modulo < 0)
+Modulo = -Modulo;
+
+  auto ComputeModuloN = [&](llvm::APSInt From, llvm::APSInt To,
+llvm::APSInt N) -> RangeSet {
+assert(N > Zero && "Non-positive N!");
+bool NonNegative = From >= Zero;
+assert(NonNegative == (To >= Zero) && "Signedness mismatch!");
+
+if (From > To)
+  return RangeFactory.getEmptySet();
+
+llvm::APSInt N1 = N - One;

danix800 wrote:

This is a problem if N is INT_MIN like value, fixed with quick return on such 
values.

https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Improve constraint inferring on concrete div/mod (PR #65448)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

> Uh, this isn't my expertiese. I'm a bit scared to do this alone. I'm also 
> short on time to verify this patch at scale.

Look forward to hear more advice! @llvm/pr-subscribers-clang-static-analyzer 

https://github.com/llvm/llvm-project/pull/65448
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][misc-include-cleaner]Avoid to insert same include header multiple times (PR #65431)

2023-09-05 Thread Ding Fei via cfe-commits

danix800 wrote:

Please refer to https://reviews.llvm.org/D159263 about `areDiagsSelfContained`.

https://github.com/llvm/llvm-project/pull/65431
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][misc-include-cleaner]Avoid to insert same include header multiple times (PR #65431)

2023-09-05 Thread Ding Fei via cfe-commits


@@ -199,6 +199,9 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult &Result) {
 
   tooling::HeaderIncludes HeaderIncludes(getCurrentMainFile(), Code,
  FileStyle->IncludeStyle);
+  // `tooling::HeaderIncludes::insert` will not modify `ExistingIncludes`. We
+  // should handle repeat include here
+  std::set InsertedHeader{};

danix800 wrote:

`std::set` won't compile, please take a look at the failed 
CI checking. `llvm::StringSet` might be better option if `std::string` could be 
switched to `StringRef`.

https://github.com/llvm/llvm-project/pull/65431
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][misc-include-cleaner]Avoid to insert same include header multiple times (PR #65431)

2023-09-05 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/65431
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy][misc-include-cleaner]Avoid to insert same include header multiple times (PR #65431)

2023-09-05 Thread Ding Fei via cfe-commits


@@ -209,14 +212,16 @@ void IncludeCleanerCheck::check(const 
MatchFinder::MatchResult &Result) {
 // main file.
 if (auto Replacement =
 HeaderIncludes.insert(llvm::StringRef{Spelling}.trim("\"<>"),

danix800 wrote:

`HeaderIncludes` is NOT a container. This `insert` means to create a 
`tooling::Replacement` object rather than container insertion/emplacing.

https://github.com/llvm/llvm-project/pull/65431
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-06 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/65448:

Fixes #54377

>From 2b04f714f1e1985546ff7ed00c131591316782b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH] [analyzer] Reduce constraint on modulo with small concrete
 range

---
 .../PathSensitive/RangedConstraintManager.h   |  1 +
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  |  3 +
 .../Core/RangeConstraintManager.cpp   | 48 +++
 .../Core/RangedConstraintManager.cpp  | 14 +
 clang/test/Analysis/constraint-assignor.c | 60 +++
 5 files changed, 126 insertions(+)

diff --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
index 49ea006e27aa54..f350cfa1cd011c 100644
--- 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
+++ 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
@@ -476,6 +476,7 @@ class RangedConstraintManager : public 
SimpleConstraintManager {
   //===--===//
 private:
   static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment);
+  static void computeScaling(SymbolRef &Sym, llvm::APSInt &ConvertedInt);
 };
 
 /// Try to simplify a given symbolic expression based on the constraints in
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 0e2ac78f7089c5..670de6795f1c2d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1702,6 +1702,9 @@ ProgramStateRef ExprEngine::escapeValues(ProgramStateRef 
State,
 
 void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet &DstTop) {
+  //  static int Count = 0;
+  //  llvm::errs() << "Count: " << Count++ << "\n";
+  //  S->dump();
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
 S->getBeginLoc(), "Error evaluating 
statement");
   ExplodedNodeSet Dst;
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c..9bda29c87f3c0f 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp 
b/cla

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-06 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/65448:

>From 235f39a6a5137e53239105727798d4540e5dd563 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 6 Sep 2023 10:03:21 +0800
Subject: [PATCH] [analyzer] Reduce constraint on modulo with small concrete
 range

---
 .../Core/RangeConstraintManager.cpp   | 48 +++
 clang/test/Analysis/constraint-assignor.c | 60 +++
 2 files changed, 108 insertions(+)

diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp 
b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 5de99384449a4c..9bda29c87f3c0f 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2073,6 +2073,14 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (Sym->getOpcode() != BO_Rem)
   return true;
 // a % b != 0 implies that a != 0.
+// Z3 verification:
+//   (declare-const a Int)
+//   (declare-const m Int)
+//   (assert (not (= m 0)))
+//   (assert (not (= (mod a m) 0)))
+//   (assert (= a 0))
+//   (check-sat)
+//   ; unsat
 if (!Constraint.containsZero()) {
   SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS());
   if (auto NonLocSymSVal = SymSVal.getAs()) {
@@ -2080,6 +2088,46 @@ class ConstraintAssignor : public 
ConstraintAssignorBase {
 if (!State)
   return false;
   }
+} else if (auto *SIE = dyn_cast(Sym);
+   SIE && Constraint.encodesFalseRange()) {
+  // a % m == 0 && a in [x, y] && y - x < m implies that
+  // a = (y < 0 ? x : y) / m * m which is a 'ConcreteInt'
+  // where x and m are 'ConcreteInt'.
+  //
+  // Z3 verification:
+  //   (declare-const a Int)
+  //   (declare-const m Int)
+  //   (declare-const x Int)
+  //   (declare-const y Int)
+  //   (assert (= (mod a m) 0))
+  //   (assert (< (- y x) m))
+  //   (assert (and (>= a x) (<= a y)))
+  //   (assert (not (= a (* (div y m) m
+  //   (check-sat)
+  //   ; unsat
+  llvm::APSInt Modulo = SIE->getRHS();
+  Modulo = llvm::APSInt(Modulo.abs(), Modulo.isUnsigned());
+  RangeSet RS =
+  SymbolicRangeInferrer::inferRange(RangeFactory, State, 
SIE->getLHS());
+  if (RS.size() == 1) {
+auto R = RS.begin();
+if ((R->To() - R->From()).getExtValue() < Modulo.getExtValue()) {
+  SVal SymSVal = Builder.makeSymbolVal(SIE->getLHS());
+  if (auto NonLocSymSVal = SymSVal.getAs()) {
+auto NewConstConstraint = Builder.makeIntVal(
+(R->To() > 0 ? R->To() : R->From()) / Modulo * Modulo);
+if (auto Cond = Builder
+.evalBinOp(State, BO_EQ, *NonLocSymSVal,
+   NewConstConstraint,
+   Builder.getConditionType())
+.template getAs()) {
+  State = State->assume(*Cond, true);
+  if (!State)
+return false;
+}
+  }
+}
+  }
 }
 return true;
   }
diff --git a/clang/test/Analysis/constraint-assignor.c 
b/clang/test/Analysis/constraint-assignor.c
index 8210e576c98bd2..150fe20c9f37a0 100644
--- a/clang/test/Analysis/constraint-assignor.c
+++ b/clang/test/Analysis/constraint-assignor.c
@@ -5,6 +5,7 @@
 
 void clang_analyzer_warnIfReached(void);
 void clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
 
 void rem_constant_rhs_ne_zero(int x, int y) {
   if (x % 3 == 0) // x % 3 != 0 -> x != 0
@@ -82,3 +83,62 @@ void remainder_with_adjustment_of_composit_lhs(int x, int y) 
{
   clang_analyzer_eval(x + y != -1);// expected-warning{{TRUE}}
   (void)(x * y); // keep the constraints alive.
 }
+
+void remainder_infeasible(int x, int y) {
+  if (x <= 2 || x >= 5)
+return;
+  if (x % 5 != 0)
+return;
+  clang_analyzer_warnIfReached(); // no-warning
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range_unsigned(unsigned x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_positive_range(int x) {
+  if (x <= 2 || x > 6)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{5 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_within_modulo_range_spans_zero(int x) {
+  if (x <= -2 || x > 2)
+return;
+  clang_analyzer_dump(x); // expected-warning{{reg_$0}}
+  if (x % 5 != 0)
+return;
+  clang_analyzer_dump(x);  // expected-warning{{0 S32b}}
+  (void)x; // keep the constraints alive.
+}
+
+void remainder_w

[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/88014

Use refactored `CheckForConstantInitializer()` to skip checking expr with error.

>From fbd0780923d40b0d8290280731239a722a7af7a9 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Tue, 9 Apr 2024 00:26:03 +0800
Subject: [PATCH] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid
 InitListExpr (#88008)

Use refactored CheckForConstantInitializer() to skip checking expr with error.
---
 clang/include/clang/Sema/Sema.h   |  2 +-
 clang/lib/Sema/SemaDecl.cpp   | 28 ---
 clang/lib/Sema/SemaExpr.cpp   |  3 +-
 .../test/Sema/recover-expr-gh88008-nocrash.c  | 11 
 4 files changed, 25 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/Sema/recover-expr-gh88008-nocrash.c

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 56d66a4486e0e7..452ccdda868b55 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3391,7 +3391,7 @@ class Sema final : public SemaBase {
   bool ConstexprSupported, bool CLinkageMayDiffer);
 
   /// type checking declaration initializers (C99 6.7.8)
-  bool CheckForConstantInitializer(Expr *e, QualType t);
+  bool CheckForConstantInitializer(Expr *Init, unsigned DiagID);
 
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
 QualType Type, TypeSourceInfo *TSI,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c790dab72dd721..a516cff166fd67 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12769,7 +12769,7 @@ void Sema::DiagnoseHLSLAttrStageMismatch(
   << (AllowedStages.size() != 1) << join(StageStrings, ", ");
 }
 
-bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
   // FIXME: Need strict checking.  In C89, we need to check for
   // any assignment, increment, decrement, function-calls, or
   // commas outside of a sizeof.  In C99, it's the same list,
@@ -12787,8 +12787,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, 
QualType DclT) {
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;
-  Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
-<< Culprit->getSourceRange();
+  Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
   return true;
 }
 
@@ -13906,29 +13905,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
 // This is true even in C++ for OpenCL.
 } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// Otherwise, C++ does not restrict the initializer.
+  // Otherwise, C++ does not restrict the initializer.
 } else if (getLangOpts().CPlusPlus) {
   // do nothing
 
 // C99 6.7.8p4: All the expressions in an initializer for an object that 
has
 // static storage duration shall be constant expressions or string 
literals.
 } else if (VDecl->getStorageClass() == SC_Static) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// C89 is stricter than C99 for aggregate initializers.
-// C89 6.5.7p3: All the expressions [...] in an initializer list
-// for an object that has aggregate or union type shall be
-// constant expressions.
+  // C89 is stricter than C99 for aggregate initializers.
+  // C89 6.5.7p3: All the expressions [...] in an initializer list
+  // for an object that has aggregate or union type shall be
+  // constant expressions.
 } else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa(Init)) {
-  const Expr *Culprit;
-  if (!Init->isConstantInitializer(Context, false, &Culprit)) {
-Diag(Culprit->getExprLoc(),
- diag::ext_aggregate_init_not_constant)
-  << Culprit->getSourceRange();
-  }
+  CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
 }
 
 if (auto *E = dyn_cast(Init))
@@ -14061,7 +14055,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // Avoid duplicate diagnostics for constexpr variables.
 if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
 !VDecl->isConstexpr())
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
   }
 
   QualType InitType = Init->getType();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8db4fffeecfe35..2016d2eb08e0ff 100644
--- a/clang/lib/Sem

[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-04-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/76619

>From 0ca1a2b2573d1f89a1b4d13cd43628a46c1e5c98 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Sun, 31 Dec 2023 00:32:01 +0800
Subject: [PATCH] [ASTMatchers] fix captureVars assertion failure on
 capturesVariables

Matcher 'capturesVar' should check for capturesVariables() before
calling getCaptureVar() since it asserts this LambdaCapture does capture
a variable.

Fixes #76425
---
 clang/docs/ReleaseNotes.rst | 1 +
 clang/include/clang/ASTMatchers/ASTMatchers.h   | 2 ++
 clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index abf15c8dc49d9e..8d9ccf789d9cb8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -633,6 +633,7 @@ AST Matchers
 - Add ``isExplicitObjectMemberFunction``.
 - Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to
   not skip the explicit object parameter for operator calls.
+- Fixed captureVars assertion failure if not capturesVariables. (#GH76425)
 
 clang-format
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 2f71053d030f68..8a2bbfff9e9e6b 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4961,6 +4961,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, 
internal::Matcher,
 /// capturesVar(hasName("x")) matches `x` and `x = 1`.
 AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher,
   InnerMatcher) {
+  if (!Node.capturesVariable())
+return false;
   auto *capturedVar = Node.getCapturedVar();
   return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
 }
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 0edc65162fbe3f..b76627cb9be637 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2321,6 +2321,8 @@ TEST_P(ASTMatchersTest, 
LambdaCaptureTest_BindsToCaptureOfVarDecl) {
   matches("int main() { int cc; auto f = [=](){ return cc; }; }", 
matcher));
   EXPECT_TRUE(
   matches("int main() { int cc; auto f = [&](){ return cc; }; }", 
matcher));
+  EXPECT_TRUE(matches(
+  "void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
 }
 
 TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {

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


[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-04-08 Thread Ding Fei via cfe-commits

danix800 wrote:

> LGTM but please add a release note so users know about the bug fix.

Release note added.

https://github.com/llvm/llvm-project/pull/76619
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-08 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/88014

>From fbd0780923d40b0d8290280731239a722a7af7a9 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Tue, 9 Apr 2024 00:26:03 +0800
Subject: [PATCH 1/2] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid
 InitListExpr (#88008)

Use refactored CheckForConstantInitializer() to skip checking expr with error.
---
 clang/include/clang/Sema/Sema.h   |  2 +-
 clang/lib/Sema/SemaDecl.cpp   | 28 ---
 clang/lib/Sema/SemaExpr.cpp   |  3 +-
 .../test/Sema/recover-expr-gh88008-nocrash.c  | 11 
 4 files changed, 25 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/Sema/recover-expr-gh88008-nocrash.c

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 56d66a4486e0e7..452ccdda868b55 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3391,7 +3391,7 @@ class Sema final : public SemaBase {
   bool ConstexprSupported, bool CLinkageMayDiffer);
 
   /// type checking declaration initializers (C99 6.7.8)
-  bool CheckForConstantInitializer(Expr *e, QualType t);
+  bool CheckForConstantInitializer(Expr *Init, unsigned DiagID);
 
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
 QualType Type, TypeSourceInfo *TSI,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c790dab72dd721..a516cff166fd67 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12769,7 +12769,7 @@ void Sema::DiagnoseHLSLAttrStageMismatch(
   << (AllowedStages.size() != 1) << join(StageStrings, ", ");
 }
 
-bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
   // FIXME: Need strict checking.  In C89, we need to check for
   // any assignment, increment, decrement, function-calls, or
   // commas outside of a sizeof.  In C99, it's the same list,
@@ -12787,8 +12787,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, 
QualType DclT) {
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;
-  Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
-<< Culprit->getSourceRange();
+  Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
   return true;
 }
 
@@ -13906,29 +13905,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
 // This is true even in C++ for OpenCL.
 } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// Otherwise, C++ does not restrict the initializer.
+  // Otherwise, C++ does not restrict the initializer.
 } else if (getLangOpts().CPlusPlus) {
   // do nothing
 
 // C99 6.7.8p4: All the expressions in an initializer for an object that 
has
 // static storage duration shall be constant expressions or string 
literals.
 } else if (VDecl->getStorageClass() == SC_Static) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// C89 is stricter than C99 for aggregate initializers.
-// C89 6.5.7p3: All the expressions [...] in an initializer list
-// for an object that has aggregate or union type shall be
-// constant expressions.
+  // C89 is stricter than C99 for aggregate initializers.
+  // C89 6.5.7p3: All the expressions [...] in an initializer list
+  // for an object that has aggregate or union type shall be
+  // constant expressions.
 } else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa(Init)) {
-  const Expr *Culprit;
-  if (!Init->isConstantInitializer(Context, false, &Culprit)) {
-Diag(Culprit->getExprLoc(),
- diag::ext_aggregate_init_not_constant)
-  << Culprit->getSourceRange();
-  }
+  CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
 }
 
 if (auto *E = dyn_cast(Init))
@@ -14061,7 +14055,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // Avoid duplicate diagnostics for constexpr variables.
 if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
 !VDecl->isConstexpr())
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
   }
 
   QualType InitType = Init->getType();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8db4fffeecfe35..2016d2eb08e0ff 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7898,7 +7898,8 @@ Sema::B

[clang] [ASTMatchers] fix captureVars assertion failure on capturesVariables (PR #76619)

2024-04-09 Thread Ding Fei via cfe-commits

https://github.com/danix800 closed 
https://github.com/llvm/llvm-project/pull/76619
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-12 Thread Ding Fei via cfe-commits

danix800 wrote:

ping @Endilll 

https://github.com/llvm/llvm-project/pull/88014
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-15 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/88014

>From 9b293d37ec5c0193e3ad4e1bab2d382ebe54d7b6 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Tue, 9 Apr 2024 00:26:03 +0800
Subject: [PATCH 1/3] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid
 InitListExpr (#88008)

Use refactored CheckForConstantInitializer() to skip checking expr with error.
---
 clang/include/clang/Sema/Sema.h   |  2 +-
 clang/lib/Sema/SemaDecl.cpp   | 28 ---
 clang/lib/Sema/SemaExpr.cpp   |  3 +-
 .../test/Sema/recover-expr-gh88008-nocrash.c  | 11 
 4 files changed, 25 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/Sema/recover-expr-gh88008-nocrash.c

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d93ac7863b721d..79bf44116d0acc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3431,7 +3431,7 @@ class Sema final : public SemaBase {
   bool ConstexprSupported, bool CLinkageMayDiffer);
 
   /// type checking declaration initializers (C99 6.7.8)
-  bool CheckForConstantInitializer(Expr *e, QualType t);
+  bool CheckForConstantInitializer(Expr *Init, unsigned DiagID);
 
   QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
 QualType Type, TypeSourceInfo *TSI,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8b3b9d020db572..6529e12e107fb7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12668,7 +12668,7 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
   }
 }
 
-bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+bool Sema::CheckForConstantInitializer(Expr *Init, unsigned DiagID) {
   // FIXME: Need strict checking.  In C89, we need to check for
   // any assignment, increment, decrement, function-calls, or
   // commas outside of a sizeof.  In C99, it's the same list,
@@ -12686,8 +12686,7 @@ bool Sema::CheckForConstantInitializer(Expr *Init, 
QualType DclT) {
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;
-  Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
-<< Culprit->getSourceRange();
+  Diag(Culprit->getExprLoc(), DiagID) << Culprit->getSourceRange();
   return true;
 }
 
@@ -13805,29 +13804,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
 // This is true even in C++ for OpenCL.
 } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// Otherwise, C++ does not restrict the initializer.
+  // Otherwise, C++ does not restrict the initializer.
 } else if (getLangOpts().CPlusPlus) {
   // do nothing
 
 // C99 6.7.8p4: All the expressions in an initializer for an object that 
has
 // static storage duration shall be constant expressions or string 
literals.
 } else if (VDecl->getStorageClass() == SC_Static) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
 
-// C89 is stricter than C99 for aggregate initializers.
-// C89 6.5.7p3: All the expressions [...] in an initializer list
-// for an object that has aggregate or union type shall be
-// constant expressions.
+  // C89 is stricter than C99 for aggregate initializers.
+  // C89 6.5.7p3: All the expressions [...] in an initializer list
+  // for an object that has aggregate or union type shall be
+  // constant expressions.
 } else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa(Init)) {
-  const Expr *Culprit;
-  if (!Init->isConstantInitializer(Context, false, &Culprit)) {
-Diag(Culprit->getExprLoc(),
- diag::ext_aggregate_init_not_constant)
-  << Culprit->getSourceRange();
-  }
+  CheckForConstantInitializer(Init, diag::ext_aggregate_init_not_constant);
 }
 
 if (auto *E = dyn_cast(Init))
@@ -13960,7 +13954,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // Avoid duplicate diagnostics for constexpr variables.
 if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
 !VDecl->isConstexpr())
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init, diag::err_init_element_not_constant);
   }
 
   QualType InitType = Init->getType();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 24f354f1c72498..4b846bb2a1bb43 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7880,7 +7880,8 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 

[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-15 Thread Ding Fei via cfe-commits


@@ -3391,7 +3391,7 @@ class Sema final : public SemaBase {
   bool ConstexprSupported, bool CLinkageMayDiffer);
 
   /// type checking declaration initializers (C99 6.7.8)
-  bool CheckForConstantInitializer(Expr *e, QualType t);
+  bool CheckForConstantInitializer(Expr *Init, unsigned DiagID);

danix800 wrote:

Thanks for reviewing, I'll add default `DiagID` to 
`diag::err_init_element_not_constant`.

https://github.com/llvm/llvm-project/pull/88014
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-15 Thread Ding Fei via cfe-commits


@@ -13805,29 +13804,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
 // This is true even in C++ for OpenCL.
 } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
-  CheckForConstantInitializer(Init, DclT);
+  CheckForConstantInitializer(Init);

danix800 wrote:

No, this defaults to `diag::err_init_element_not_constant`.

https://github.com/llvm/llvm-project/pull/88014
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AST][RecoveryExpr] Fix a crash on c89/c90 invalid InitListExpr (#88008) (PR #88014)

2024-04-16 Thread Ding Fei via cfe-commits

https://github.com/danix800 closed 
https://github.com/llvm/llvm-project/pull/88014
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/89096

Lambda without trailing auto could has return type declared inside the body too.

>From 6390eb0618e88c1c176329c6d49a45e16944f248 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:03:14 +0800
Subject: [PATCH] [ASTImporter] Fix infinite recurse on return type declared
 inside body (#68775)

Lambda without trailing auto could has return type declared inside the
body too.
---
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

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


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0f7ddbfef8ca9c93efacfb2a437ddb5645ca07b1 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:03:14 +0800
Subject: [PATCH] [ASTImporter] Fix infinite recurse on return type declared
 inside body (#68775)

Lambda without trailing auto could has return type declared inside the
body too.
---
 .cproject   | 125 
 .project|  27 +
 .settings/language.settings.xml |  27 +
 .settings/org.eclipse.cdt.core.prefs|   6 +
 clang/docs/ReleaseNotes.rst |   2 +
 clang/lib/AST/ASTImporter.cpp   |  16 +--
 clang/unittests/AST/ASTImporterTest.cpp |  16 +++
 expand-modular-headers-ppcallbacks.cpp.diff |  55 +
 8 files changed, 264 insertions(+), 10 deletions(-)
 create mode 100644 .cproject
 create mode 100644 .project
 create mode 100644 .settings/language.settings.xml
 create mode 100644 .settings/org.eclipse.cdt.core.prefs
 create mode 100644 expand-modular-headers-ppcallbacks.cpp.diff

diff --git a/.cproject b/.cproject
new file mode 100644
index 00..36ee502ff51294
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,125 @@
+
+
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   

+   

+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+   
+

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH] [ASTImporter] Fix infinite recurse on return type declared
 inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

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


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH 1/2] [ASTImporter] Fix infinite recurse on return type
 declared inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 3f1d714a2aa4b236afe9bb1384be073fb155a2b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 08:56:56 +0800
Subject: [PATCH 2/2] Limit TypeVisitor checking to 'auto' and lambda
 definition only

1. Fix potential perf regression;
2. Fix comment.
---
 clang/lib/AST/ASTImporter.cpp | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bbd6ebaf1..d98cb80c349db2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3647,17 +3647,25 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
 bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits


@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.

danix800 wrote:

Thanks for reminding, fixed in 
https://github.com/llvm/llvm-project/pull/89096/commits/3f1d714a2aa4b236afe9bb1384be073fb155a2b8

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

danix800 wrote:

> I think it would be a good idea to double check this for performance 
> regressions, since this case will recurse into the function every time with 
> this patch. Though I don't know if there is a better way to test it than to 
> merge it and wait for it to be picked up by google.

For large TU it's worth considering for performance. The previous commit 
relaxed the `TypeVisitor` checking to all `FunctionDecl`. I reverted back to 
the original `auto` impl, plus an extra condition that if it's a `lambda` 
definition, see 
https://github.com/llvm/llvm-project/pull/89096/commits/3f1d714a2aa4b236afe9bb1384be073fb155a2b8

> 
> Another idea to avoid any potential regressions, is to mark the return type 
> as deduced anyway, with the distinction that 'auto' was not written.

I tested this idea, might be like this:
```
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 712958594473..988efcbef3a3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3680,24 +3680,10 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
-  FromReturnTy = Importer.getFromContext().VoidTy;
-  UsedDifferentProtoType = true;
-}
-FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
-// FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
-// FunctionDecl that we are importing the FunctionProtoType for.
-// To avoid an infinite recursion when importing, create the FunctionDecl
-// with a simplified function type.
-if (FromEPI.ExceptionSpec.SourceDecl ||
-FromEPI.ExceptionSpec.SourceTemplate ||
-FromEPI.ExceptionSpec.NoexceptExpr) {
-  FunctionProtoType::ExtProtoInfo DefaultEPI;
-  FromEPI = DefaultEPI;
-  UsedDifferentProtoType = true;
-}
+FunctionProtoType::ExtProtoInfo DefaultEPI;
+UsedDifferentProtoType = true;
 FromTy = Importer.getFromContext().getFunctionType(
-FromReturnTy, FromFPT->getParamTypes(), FromEPI);
+Importer.getFromContext().VoidTy, FromFPT->getParamTypes(), 
DefaultEPI);
 FromTSI = Importer.getFromContext().getTrivialTypeSourceInfo(
 FromTy, D->getBeginLoc());
   }
```
but this will break two testcases from `check-clang-astmerge-exprs-cpp`:
```
Failed Tests (2):
  Clang :: ASTMerge/class-template/test.cpp
  Clang :: ASTMerge/exprs-cpp/test.cpp
```

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits


@@ -3647,15 +3647,19 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_cast(D))
+IsLambdaDefinition = cast(MD->getDeclContext())->isLambda();

danix800 wrote:

> Thanks, this works, but if we are going this way, why not also check the 
> lambda was defined without a return type?

Could you please give some direction on how to test **the lambda was defined 
without a return type**?

Does this mean that we need to check for possible `return` statements within 
lambda?

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits


@@ -3647,15 +3647,19 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_cast(D))
+IsLambdaDefinition = cast(MD->getDeclContext())->isLambda();

danix800 wrote:

Or does this mean to test `!FromFPT->hasTrailingReturn()`?

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits


@@ -3647,15 +3647,19 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_cast(D))
+IsLambdaDefinition = cast(MD->getDeclContext())->isLambda();

danix800 wrote:

Got it! Thanks for these useful info!

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH 1/3] [ASTImporter] Fix infinite recurse on return type
 declared inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 3f1d714a2aa4b236afe9bb1384be073fb155a2b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 08:56:56 +0800
Subject: [PATCH 2/3] Limit TypeVisitor checking to 'auto' and lambda
 definition only

1. Fix potential perf regression;
2. Fix comment.
---
 clang/lib/AST/ASTImporter.cpp | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bbd6ebaf1..d98cb80c349db2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3647,17 +3647,25 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
 bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH 1/4] [ASTImporter] Fix infinite recurse on return type
 declared inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 3f1d714a2aa4b236afe9bb1384be073fb155a2b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 08:56:56 +0800
Subject: [PATCH 2/4] Limit TypeVisitor checking to 'auto' and lambda
 definition only

1. Fix potential perf regression;
2. Fix comment.
---
 clang/lib/AST/ASTImporter.cpp | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bbd6ebaf1..d98cb80c349db2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3647,17 +3647,25 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
 bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-17 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH 1/5] [ASTImporter] Fix infinite recurse on return type
 declared inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 3f1d714a2aa4b236afe9bb1384be073fb155a2b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 08:56:56 +0800
Subject: [PATCH 2/5] Limit TypeVisitor checking to 'auto' and lambda
 definition only

1. Fix potential perf regression;
2. Fix comment.
---
 clang/lib/AST/ASTImporter.cpp | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bbd6ebaf1..d98cb80c349db2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3647,17 +3647,25 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
 bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-18 Thread Ding Fei via cfe-commits


@@ -3647,15 +3647,28 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  auto IsCXX11LambdaWithouTrailingReturn = [&]() {
+if (!Importer.FromContext.getLangOpts().CPlusPlus11)

danix800 wrote:

These `CPlusPlus` / `CPlusPlus11` / `CPlusPlus14` options are really misleading 
if no comments explaining how they works. Thanks for pointing this out!

https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-18 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/89096

>From 0d6d52365a5d31045c347412c3a0fe8be7119006 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 00:33:29 +0800
Subject: [PATCH 1/6] [ASTImporter] Fix infinite recurse on return type
 declared inside body (#68775)

Lambda without trailing auto could has return type declared
inside the body too.
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/AST/ASTImporter.cpp   | 16 ++--
 clang/unittests/AST/ASTImporterTest.cpp | 16 
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..7a623c6be72fd2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,8 @@ Bug Fixes to AST Handling
 Miscellaneous Bug Fixes
 ^^^
 
+- Fixed an infinite recursion on return type declared inside body (#GH68775).
+
 Miscellaneous Clang Crashes Fixed
 ^
 
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6aaa34c55ce307..3bbd6ebaf1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -695,7 +695,7 @@ namespace clang {
 // Returns true if the given function has a placeholder return type and
 // that type is declared inside the body of the function.
 // E.g. auto f() { struct X{}; return X(); }
-bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
+bool hasReturnTypeDeclaredInside(FunctionDecl *D);
   };
 
 template 
@@ -3649,19 +3649,15 @@ class IsTypeDeclaredInsideVisitor
 
 /// This function checks if the function has 'auto' return type that contains
 /// a reference (in any way) to a declaration inside the same function.
-bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
+bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr())) {
-FunctionDecl *Def = D->getDefinition();
-IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
-return Visitor.CheckType(RetT);
-  }
-
-  return false;
+  FunctionDecl *Def = D->getDefinition();
+  IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
+  return Visitor.CheckType(RetT);
 }
 
 ExplicitSpecifier
@@ -3811,7 +3807,7 @@ ExpectedDecl 
ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 // E.g.: auto foo() { struct X{}; return X(); }
 // To avoid an infinite recursion when importing, create the FunctionDecl
 // with a simplified return type.
-if (hasAutoReturnTypeDeclaredInside(D)) {
+if (hasReturnTypeDeclaredInside(D)) {
   FromReturnTy = Importer.getFromContext().VoidTy;
   UsedDifferentProtoType = true;
 }
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index acc596fef87b76..3fac5514319c24 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6721,6 +6721,22 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
LambdaInFunctionBody) {
   EXPECT_FALSE(FromL->isDependentLambda());
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaReturnTypeDeclaredInside) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) []() {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo");
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 3f1d714a2aa4b236afe9bb1384be073fb155a2b8 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 18 Apr 2024 08:56:56 +0800
Subject: [PATCH 2/6] Limit TypeVisitor checking to 'auto' and lambda
 definition only

1. Fix potential perf regression;
2. Fix comment.
---
 clang/lib/AST/ASTImporter.cpp | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bbd6ebaf1..d98cb80c349db2 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3647,17 +3647,25 @@ class IsTypeDeclaredInsideVisitor
 };
 } // namespace
 
-/// This function checks if the function has 'auto' return type that contains
+/// This function checks if the given function has a return type that contains
 /// a reference (in any way) to a declaration inside the same function.
 bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   QualType FromTy = D->getType();
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
+  bool IsLambdaDefinition = false;
+  if (const auto *MD = dyn_

[clang] [ASTImporter] Fix infinite recurse on return type declared inside body (#68775) (PR #89096)

2024-04-19 Thread Ding Fei via cfe-commits

https://github.com/danix800 closed 
https://github.com/llvm/llvm-project/pull/89096
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter][NFC] add unittests for unnamed EnumDecl (PR #100545)

2024-07-25 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/100545

These tests are for multiple anonymous EnumDecls structural eq test & importing.

We found the anonymous enums importing issue a few days ago and tried to fix it
but 0a6233a68c7b575d05bca0f0c708b7e97cc710d1 already did this. I think these 
tests are still useful for regressions.

>From 2365cb103365994df0669e003a6afdeffb4d34e5 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Thu, 25 Jul 2024 17:37:56 +0800
Subject: [PATCH] [clang][ASTImporter][NFC] add unittests for unnamed EnumDecl

These tests are for 0a6233a68c7b575d05bca0f0c708b7e97cc710d1
multiple anonymous EnumDecls structural eq test & importing.
---
 clang/unittests/AST/ASTImporterTest.cpp   | 37 +++
 .../AST/StructuralEquivalenceTest.cpp | 14 +++
 2 files changed, 51 insertions(+)

diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 6d987cc7e9ec6..9b12caa37cf79 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9783,6 +9783,43 @@ TEST_P(ASTImporterOptionSpecificTestBase, 
ImportExistingEmptyAnonymousEnums) {
   EXPECT_EQ(ImportedE2, ToE1);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, ImportMultipleAnonymousEnumDecls) {
+  Decl *ToTU = getToTuDecl("", Lang_CXX03);
+  Decl *FromTU = getTuDecl(
+  R"(
+struct foo {
+  enum { A };
+  enum { B };
+};
+  )",
+  Lang_CXX03);
+
+  auto EnumConstA = enumConstantDecl(hasName("A"));
+  auto EnumConstB = enumConstantDecl(hasName("B"));
+
+  auto *FromA = FirstDeclMatcher().match(FromTU, EnumConstA);
+  auto *FromB = FirstDeclMatcher().match(FromTU, EnumConstB);
+
+  auto *ToA = Import(FromA, Lang_CXX03);
+  auto *ToB = Import(FromB, Lang_CXX03);
+
+  ASSERT_TRUE(ToA);
+  ASSERT_TRUE(ToB);
+
+  auto *ToFooA = FirstDeclMatcher().match(
+  ToTU, tagDecl(has(enumDecl(has(EnumConstA);
+  auto *ToFooB = FirstDeclMatcher().match(
+  ToTU, tagDecl(has(enumDecl(has(EnumConstB);
+  ASSERT_EQ(ToFooA, ToFooB);
+
+  // different EnumDecl
+  auto *ToEnumDeclA =
+  FirstDeclMatcher().match(ToTU, enumDecl(has(EnumConstA)));
+  auto *ToEnumDeclB =
+  FirstDeclMatcher().match(ToTU, enumDecl(has(EnumConstB)));
+  ASSERT_NE(ToEnumDeclA, ToEnumDeclB);
+}
+
 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
  DefaultTestValuesForRunOptions);
 
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 952c83be0cb64..e994086c99d04 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1109,6 +1109,20 @@ TEST_F(StructuralEquivalenceEnumTest, 
EnumsWithDifferentBody) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithSameConsts) {
+  // field x is required to trigger comparison of the anonymous enum
+  auto t = makeNamedDecls("struct foo { enum { A } x; };",
+  "struct foo { enum { A } x;};", Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest, AnonymousEnumsWithDiffConsts) {
+  // field x is required to trigger comparison of the anonymous enum
+  auto t = makeNamedDecls("struct foo { enum { A } x; };",
+  "struct foo { enum { B } x;};", Lang_CXX11);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 struct StructuralEquivalenceEnumConstantTest : StructuralEquivalenceTest {};
 
 TEST_F(StructuralEquivalenceEnumConstantTest, EnumConstantsWithSameValues) {

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


[clang] [clang][ASTImporter][NFC] add unittests for unnamed EnumDecl (PR #100545)

2024-07-25 Thread Ding Fei via cfe-commits

https://github.com/danix800 closed 
https://github.com/llvm/llvm-project/pull/100545
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-29 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/101031

…roto

The test should be true on function with trailing return.

This fixes crashes (infinite recursion) on lambda expr without parameters 
(without parentheses).

>From 336bebf7d20feb7a6fab5ad038239b058f62bdfb Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Mon, 29 Jul 2024 23:18:20 +0800
Subject: [PATCH] [clang][ASTImporter] Fix typos in trailing return testing on
 lambda proto

The test should be true on function with trailing return.
This fixes crashes (infinite recursion) on lambda expr without parameters
(without parentheses).
---
 clang/lib/AST/ASTImporter.cpp   |  8 +++-
 clang/unittests/AST/ASTImporterTest.cpp | 17 +
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index da1981d8dd05f..83aa017a00a7f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3665,13 +3665,10 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
-  auto IsCXX11LambdaWithouTrailingReturn = [&]() {
+  auto IsCXX11LambdaWithoutTrailingReturn = [&]() {
 if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
   return false;
 
-if (FromFPT->hasTrailingReturn())
-  return false;
-
 if (const auto *MD = dyn_cast(D))
   return cast(MD->getDeclContext())->isLambda();
 
@@ -3679,7 +3676,8 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   };
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) 
{
+  if (FromFPT->hasTrailingReturn() || isa(RetT.getTypePtr()) ||
+  IsCXX11LambdaWithoutTrailingReturn()) {
 FunctionDecl *Def = D->getDefinition();
 IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
 return Visitor.CheckType(RetT);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 57c5f79651824..d275a08dca895 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6738,6 +6738,23 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_TRUE(ToLambda);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) [] {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

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


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-29 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-29 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 ready_for_review 
https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

danix800 wrote:

This commit surfaces another crash on null stmt inside `CXXDeductionGuideDecl`:

```c
namespace foo {
  template  struct is_same;
  template  struct enable_if {};
  template 
using enable_if_t = typename enable_if<_Cond, _Tp>::type;

  template 
inline constexpr bool is_same_v = is_same<_Tp, _Up>::value;

  template  struct array {};

  template 
array(_Tp, _Up...) ->
array && ...)>, _Tp>;
}
```

Will crash when imported:

```
 #0 0x7f15958323ca llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
/home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:567:11
 #1 0x7f159583257b PrintStackTraceSignalHandler(void*) 
/home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:641:1
 #2 0x7f1595830bd6 llvm::sys::RunSignalHandlers() 
/home/danis/Sources/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x7f1595832ca5 SignalHandler(int) 
/home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:412:1
 #4 0x7f159525b050 (/lib/x86_64-linux-gnu/libc.so.6+0x3c050)
 #5 0x7f159721022c clang::Stmt::getStmtClass() const 
/home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1178:44
 #6 0x7f1597aab9f1 clang::Stmt::children() 
/home/danis/Sources/llvm-project/clang/lib/AST/Stmt.cpp:287:3
 #7 0x7f159734912a clang::Stmt::children() const 
/home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1273:39
 #8 0x7f15973f3d61 clang::Stmt::child_begin() const 
/home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1279:53
 #9 0x7f15973b9746 isAncestorDeclContextOf(clang::DeclContext const*, 
clang::Stmt const*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3377:47
#10 0x7f15973b9c38 (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::checkTemplateArgument(clang::TemplateArgument
 const&) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3507:7
#11 0x7f15973b93fe (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::VisitTemplateSpecializationType(clang::TemplateSpecializationType
 const*) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3467:11
#12 0x7f15973b89b9 clang::TypeVisitor<(anonymous 
namespace)::IsTypeDeclaredInsideVisitor, 
std::optional>::Visit(clang::Type const*) 
/home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/TypeNodes.inc:71:1
#13 0x7f1597385113 (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::CheckType(clang::QualType) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3426:37
#14 0x7f15973b9c0e (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::checkTemplateArgument(clang::TemplateArgument
 const&) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3505:7
#15 0x7f15973b93fe (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::VisitTemplateSpecializationType(clang::TemplateSpecializationType
 const*) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3467:11
#16 0x7f15973b89b9 clang::TypeVisitor<(anonymous 
namespace)::IsTypeDeclaredInsideVisitor, 
std::optional>::Visit(clang::Type const*) 
/home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/TypeNodes.inc:71:1
#17 0x7f1597385113 (anonymous 
namespace)::IsTypeDeclaredInsideVisitor::CheckType(clang::QualType) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3426:37
#18 0x7f1597384f42 
clang::ASTNodeImporter::hasReturnTypeDeclaredInside(clang::FunctionDecl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3556:5
#19 0x7f1597385d8e 
clang::ASTNodeImporter::VisitFunctionDecl(clang::FunctionDecl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3709:9
#20 0x7f1597387fab 
clang::ASTNodeImporter::VisitCXXDeductionGuideDecl(clang::CXXDeductionGuideDecl*)
 /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3962:10
#21 0x7f15973e238e clang::declvisitor::Base>::Visit(clang::Decl*) 
/home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:437:1
#22 0x7f15973ad9ed clang::ASTImporter::ImportImpl(clang::Decl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:8828:19
#23 0x7f1597391055 clang::ASTImporter::Import(clang::Decl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:9219:8
#24 0x7f15973d30f7 llvm::Error 
clang::ASTNodeImporter::importInto(clang::FunctionDecl*&, 
clang::FunctionDecl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:193:11
#25 0x7f159739a2c7 
clang::ASTNodeImporter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:6502:13
#26 0x7f15973e217e clang::declvisitor::Base>::Visit(clang::Decl*) 
/home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:245:1
#27 0x7f15973ad9ed clang::ASTImporter::ImportImpl(clang::Decl*) 
/home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:8828:19
#28 0x7f1597391055 clang::

[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/101031

>From 336bebf7d20feb7a6fab5ad038239b058f62bdfb Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Mon, 29 Jul 2024 23:18:20 +0800
Subject: [PATCH 1/2] [clang][ASTImporter] Fix typos in trailing return testing
 on lambda proto

The test should be true on function with trailing return.
This fixes crashes (infinite recursion) on lambda expr without parameters
(without parentheses).
---
 clang/lib/AST/ASTImporter.cpp   |  8 +++-
 clang/unittests/AST/ASTImporterTest.cpp | 17 +
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index da1981d8dd05f..83aa017a00a7f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3665,13 +3665,10 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
-  auto IsCXX11LambdaWithouTrailingReturn = [&]() {
+  auto IsCXX11LambdaWithoutTrailingReturn = [&]() {
 if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
   return false;
 
-if (FromFPT->hasTrailingReturn())
-  return false;
-
 if (const auto *MD = dyn_cast(D))
   return cast(MD->getDeclContext())->isLambda();
 
@@ -3679,7 +3676,8 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   };
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) 
{
+  if (FromFPT->hasTrailingReturn() || isa(RetT.getTypePtr()) ||
+  IsCXX11LambdaWithoutTrailingReturn()) {
 FunctionDecl *Def = D->getDefinition();
 IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
 return Visitor.CheckType(RetT);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 57c5f79651824..d275a08dca895 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6738,6 +6738,23 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_TRUE(ToLambda);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) [] {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

>From 25101a790ac72df27e3ea766ee7db47abe0e3135 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Wed, 31 Jul 2024 10:29:12 +0800
Subject: [PATCH 2/2] remove trailing return test

Lambdas without trailing return could also have return type defined
inside its body.
---
 clang/lib/AST/ASTImporter.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 83aa017a00a7f..b1c7c400861bc 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3665,7 +3665,7 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
-  auto IsCXX11LambdaWithoutTrailingReturn = [&]() {
+  auto IsCXX11Lambda = [&]() {
 if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
   return false;
 
@@ -3676,8 +3676,7 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   };
 
   QualType RetT = FromFPT->getReturnType();
-  if (FromFPT->hasTrailingReturn() || isa(RetT.getTypePtr()) ||
-  IsCXX11LambdaWithoutTrailingReturn()) {
+  if (isa(RetT.getTypePtr()) || IsCXX11Lambda()) {
 FunctionDecl *Def = D->getDefinition();
 IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
 return Visitor.CheckType(RetT);

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


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/101031

>From 1e832ad408710d8a896d64e01a9fbf8b9c7a7819 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Mon, 29 Jul 2024 23:18:20 +0800
Subject: [PATCH] [clang][ASTImporter] Remove trailing return testing on lambda
 proto

Lambdas without trailing return could also have return type defined
inside its body.

This fixes crashes (infinite recursion) on lambda expr without parameters
(without parentheses after []).
---
 clang/lib/AST/ASTImporter.cpp   |  7 ++-
 clang/unittests/AST/ASTImporterTest.cpp | 17 +
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index da1981d8dd05f..b1c7c400861bc 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3665,13 +3665,10 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
-  auto IsCXX11LambdaWithouTrailingReturn = [&]() {
+  auto IsCXX11Lambda = [&]() {
 if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
   return false;
 
-if (FromFPT->hasTrailingReturn())
-  return false;
-
 if (const auto *MD = dyn_cast(D))
   return cast(MD->getDeclContext())->isLambda();
 
@@ -3679,7 +3676,7 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   };
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) 
{
+  if (isa(RetT.getTypePtr()) || IsCXX11Lambda()) {
 FunctionDecl *Def = D->getDefinition();
 IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
 return Visitor.CheckType(RetT);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 57c5f79651824..d275a08dca895 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6738,6 +6738,23 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_TRUE(ToLambda);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) [] {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

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


[clang] [clang][ASTImporter] Fix typos in trailing return testing on lambda p… (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 updated 
https://github.com/llvm/llvm-project/pull/101031

>From 35caf00e707b4fb2472d1409e34be7d20e4eeec2 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Mon, 29 Jul 2024 23:18:20 +0800
Subject: [PATCH] [clang][ASTImporter] Remove trailing return testing on lambda
 proto

Lambdas without trailing return could also have return type defined
inside its body.

This fixes crashes (infinite recursion) on lambda expr without parameters
(without parentheses after []).
---
 clang/lib/AST/ASTImporter.cpp   |  7 ++-
 clang/unittests/AST/ASTImporterTest.cpp | 17 +
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 103235547f482..e1c94f9b6e68d 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3713,13 +3713,10 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   const auto *FromFPT = FromTy->getAs();
   assert(FromFPT && "Must be called on FunctionProtoType");
 
-  auto IsCXX11LambdaWithouTrailingReturn = [&]() {
+  auto IsCXX11Lambda = [&]() {
 if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
   return false;
 
-if (FromFPT->hasTrailingReturn())
-  return false;
-
 if (const auto *MD = dyn_cast(D))
   return cast(MD->getDeclContext())->isLambda();
 
@@ -3727,7 +3724,7 @@ bool 
ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
   };
 
   QualType RetT = FromFPT->getReturnType();
-  if (isa(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) 
{
+  if (isa(RetT.getTypePtr()) || IsCXX11Lambda()) {
 FunctionDecl *Def = D->getDefinition();
 IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
 return Visitor.CheckType(RetT);
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 57242ff49fe3b..986c3d2636aa5 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6738,6 +6738,23 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_TRUE(ToLambda);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+   ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
+  void foo() {
+(void) [] {
+  struct X {};
+  return X();
+};
+  }
+  )",
+  Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
+  auto *ToLambda = FirstDeclMatcher().match(To, lambdaExpr());
+  EXPECT_TRUE(ToLambda);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
   Decl *FromTU = getTuDecl(
   R"(

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


[clang] [clang][ASTImporter] Remove trailing return testing on lambda proto (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Remove trailing return testing on lambda proto (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Remove trailing return testing on lambda proto (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

danix800 wrote:

> > Another PR would fix the crash when this one is landed.
> 
> Can you land the fix for the crash first? If the other PR gets reverted it 
> creates a lot of churn, so it would preferable to land that first. Assuming 
> it is not somehow dependent on this fix.

This new crash is a false alarm caused by the first incorrect fix. Sorry about 
that!

Could you also take a look at the new fix for the first crash?

Previously we think that lambda without trailing return couldn't
have return type defined inside its body, but for
```c
  [] { // no parentheses for parameters
struct X {};
return X();
  };
```
the proto has trailing return deduced to the type defined inside.

So I think we should remove the trailing return test for lambdas.

https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] Remove trailing return testing on lambda proto (PR #101031)

2024-07-30 Thread Ding Fei via cfe-commits

danix800 wrote:

> This commit surfaces another crash on null stmt inside 
> `CXXDeductionGuideDecl`:
> 
> ```c
> namespace foo {
>   template  struct is_same;
>   template  struct enable_if {};
>   template 
> using enable_if_t = typename enable_if<_Cond, _Tp>::type;
> 
>   template 
> inline constexpr bool is_same_v = is_same<_Tp, _Up>::value;
> 
>   template  struct array {};
> 
>   template 
> array(_Tp, _Up...) ->
> array && ...)>, _Tp>;
> }
> ```
> 
> Will crash when imported:
> 
> ```
>  #0 0x7f15958323ca llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
> /home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:567:11
>  #1 0x7f159583257b PrintStackTraceSignalHandler(void*) 
> /home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:641:1
>  #2 0x7f1595830bd6 llvm::sys::RunSignalHandlers() 
> /home/danis/Sources/llvm-project/llvm/lib/Support/Signals.cpp:104:5
>  #3 0x7f1595832ca5 SignalHandler(int) 
> /home/danis/Sources/llvm-project/llvm/lib/Support/Unix/Signals.inc:412:1
>  #4 0x7f159525b050 (/lib/x86_64-linux-gnu/libc.so.6+0x3c050)
>  #5 0x7f159721022c clang::Stmt::getStmtClass() const 
> /home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1178:44
>  #6 0x7f1597aab9f1 clang::Stmt::children() 
> /home/danis/Sources/llvm-project/clang/lib/AST/Stmt.cpp:287:3
>  #7 0x7f159734912a clang::Stmt::children() const 
> /home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1273:39
>  #8 0x7f15973f3d61 clang::Stmt::child_begin() const 
> /home/danis/Sources/llvm-project/clang/include/clang/AST/Stmt.h:1279:53
>  #9 0x7f15973b9746 isAncestorDeclContextOf(clang::DeclContext const*, 
> clang::Stmt const*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3377:47
> #10 0x7f15973b9c38 (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::checkTemplateArgument(clang::TemplateArgument
>  const&) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3507:7
> #11 0x7f15973b93fe (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::VisitTemplateSpecializationType(clang::TemplateSpecializationType
>  const*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3467:11
> #12 0x7f15973b89b9 clang::TypeVisitor<(anonymous 
> namespace)::IsTypeDeclaredInsideVisitor, 
> std::optional>::Visit(clang::Type const*) 
> /home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/TypeNodes.inc:71:1
> #13 0x7f1597385113 (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::CheckType(clang::QualType) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3426:37
> #14 0x7f15973b9c0e (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::checkTemplateArgument(clang::TemplateArgument
>  const&) /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3505:7
> #15 0x7f15973b93fe (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::VisitTemplateSpecializationType(clang::TemplateSpecializationType
>  const*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3467:11
> #16 0x7f15973b89b9 clang::TypeVisitor<(anonymous 
> namespace)::IsTypeDeclaredInsideVisitor, 
> std::optional>::Visit(clang::Type const*) 
> /home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/TypeNodes.inc:71:1
> #17 0x7f1597385113 (anonymous 
> namespace)::IsTypeDeclaredInsideVisitor::CheckType(clang::QualType) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3426:37
> #18 0x7f1597384f42 
> clang::ASTNodeImporter::hasReturnTypeDeclaredInside(clang::FunctionDecl*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3556:5
> #19 0x7f1597385d8e 
> clang::ASTNodeImporter::VisitFunctionDecl(clang::FunctionDecl*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3709:9
> #20 0x7f1597387fab 
> clang::ASTNodeImporter::VisitCXXDeductionGuideDecl(clang::CXXDeductionGuideDecl*)
>  /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:3962:10
> #21 0x7f15973e238e clang::declvisitor::Base clang::ASTNodeImporter, llvm::Expected>::Visit(clang::Decl*) 
> /home/danis/Sources/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:437:1
> #22 0x7f15973ad9ed clang::ASTImporter::ImportImpl(clang::Decl*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:8828:19
> #23 0x7f1597391055 clang::ASTImporter::Import(clang::Decl*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:9219:8
> #24 0x7f15973d30f7 llvm::Error 
> clang::ASTNodeImporter::importInto(clang::FunctionDecl*&,
>  clang::FunctionDecl*) 
> /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:193:11
> #25 0x7f159739a2c7 
> clang::ASTNodeImporter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl*)
>  /home/danis/Sources/llvm-project/clang/lib/AST/ASTImporter.cpp:6502:13
> #26 0x7f15973e217e clang::declvisitor::Base clang::ASTNodeImporter, llvm::Expected>::Visit(cla

[clang] [clang][ASTImporter] Remove trailing return testing on lambda proto (PR #101031)

2024-07-31 Thread Ding Fei via cfe-commits

danix800 wrote:

> > Here can `ToProcess.append(CurrentS->child_begin(), 
> > CurrentS->child_end());` add any nullptr into `ToProcess` in this testing 
> > context?
> 
> I think it is possible, but I could not reproduce this case with the shown 
> code.

We have over 30 C++ open-source projects (including AOSP) in our pipeline to
test against potential crashes in the Static Analyzer with CTU enabled, the 
pipeline
can surfaces a few problems in the ASTImporter.

I can improve `isAncestorDeclContextOf` if we really can catch crashes.

https://github.com/llvm/llvm-project/pull/101031
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTImporter] support import return with UnaryTransformType (PR #101517)

2024-08-01 Thread Ding Fei via cfe-commits

https://github.com/danix800 created 
https://github.com/llvm/llvm-project/pull/101517

This fixes infinite recursion crash on return with UnaryTransformType,
whose underlying type is a SubstTemplateTypeParmType which is
associated with current imported function.

>From 3b787c88dafc287b9a5a7aea2afba6c3fc6dead1 Mon Sep 17 00:00:00 2001
From: dingfei 
Date: Fri, 2 Aug 2024 00:46:57 +0800
Subject: [PATCH] [clang][ASTImporter] support import return with
 UnaryTransformType

This fixes infinite recursion crash on return with UnaryTransformType,
whose underlying type is a SubstTemplateTypeParmType which is associated
with current imported function.
---
 clang/lib/AST/ASTImporter.cpp   |  4 
 clang/unittests/AST/ASTImporterTest.cpp | 19 +++
 2 files changed, 23 insertions(+)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 103235547f482..157fa40163122 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3636,6 +3636,10 @@ class IsTypeDeclaredInsideVisitor
 return {};
   }
 
+  std::optional VisitUnaryTransformType(const UnaryTransformType *T) {
+return CheckType(T->getBaseType());
+  }
+
   std::optional
   VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
 // The "associated declaration" can be the same as ParentDC.
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 57242ff49fe3b..fd9be92d3792a 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -7581,6 +7581,25 @@ TEST_P(ImportAutoFunctions, 
ReturnWithSubstNonTypeTemplateParmExpr) {
   EXPECT_TRUE(ToBar);
 }
 
+TEST_P(ImportAutoFunctions, ReturnWithUnaryTransformType) {
+  const char *Code =
+  R"(
+enum E { E1 };
+
+template
+auto foo(T v) { return static_cast<__underlying_type(T)>(v); }
+
+bool bar() { return foo(E1); }
+  )";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX17);
+
+  auto *FromBar = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("bar")));
+
+  auto *ToBar = Import(FromBar, Lang_CXX17);
+  EXPECT_TRUE(ToBar);
+}
+
 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
 
 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {

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


[clang] [clang][ASTMatcher] Add matcher for 'matches' (PR #102152)

2024-08-06 Thread Ding Fei via cfe-commits


@@ -5582,6 +5582,20 @@ Narrowing Matchers
 
 
 
+MatcherStringLiteral>matchesStringRef RegExp, Regex::RegexFlags 
Flags = NoFlags

danix800 wrote:

```suggestion
MatcherStringLiteral>matchesStringRef RegExp, Regex::RegexFlags Flags 
= NoFlags
```

https://github.com/llvm/llvm-project/pull/102152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Add matcher for 'matches' (PR #102152)

2024-08-06 Thread Ding Fei via cfe-commits


@@ -288,6 +288,8 @@ AST Matchers
 - Fixed an issue with the `hasName` and `hasAnyName` matcher when matching
   inline namespaces with an enclosing namespace of the same name.
 
+- Add ``matches``.

danix800 wrote:

```suggestion
- Add `matches` for `StringLiteral` which matches literals on given `RegExp`.
```

https://github.com/llvm/llvm-project/pull/102152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ASTMatcher] Add `matchesString` for `StringLiteral` which matches literals on given `RegExp` (PR #102152)

2024-08-07 Thread Ding Fei via cfe-commits

https://github.com/danix800 edited 
https://github.com/llvm/llvm-project/pull/102152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >