[clang] fix: C++ empty record with align lead to va_list out of sync (PR #72197)

2023-11-24 Thread via cfe-commits

https://github.com/hstk30-hw updated 
https://github.com/llvm/llvm-project/pull/72197

>From 2c8d9c8dcd9780749b788bc3029fc45373007ae0 Mon Sep 17 00:00:00 2001
From: hstk30-hw 
Date: Sat, 18 Nov 2023 11:00:29 +
Subject: [PATCH] fix: empty record size > 64 with align let va_list get out of
 sync

---
 clang/lib/CodeGen/Targets/AArch64.cpp |  9 +---
 clang/test/CodeGen/aarch64-args.cpp   | 23 +--
 .../CodeGen/arm64-microsoft-arguments.cpp |  4 ++--
 clang/test/CodeGenCXX/aarch64-arguments.cpp   |  2 +-
 clang/test/CodeGenCXX/arm64-darwinpcs.cpp |  2 +-
 5 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp 
b/clang/lib/CodeGen/Targets/AArch64.cpp
index be5145daa00b7f5..d0df2813dd72f6a 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -295,8 +295,12 @@ AArch64ABIInfo::classifyArgumentType(QualType Ty, bool 
IsVariadic,
  CGCXXABI::RAA_DirectInMemory);
   }
 
-  // Empty records are always ignored on Darwin, but actually passed in C++ 
mode
-  // elsewhere for GNU compatibility.
+  // AAPCS64 does not say that empty records are ignored as arguments,
+  // but other compilers do so in certain situations, and we copy that 
behavior.
+  // Those situations are in fact language-mode-specific, which seems really
+  // unfortunate, but it's something we just have to accept. If this doesn't
+  // apply, just fall through to the standard argument-handling path.
+  // Darwin overrides the psABI here to ignore all empty records in all modes.
   uint64_t Size = getContext().getTypeSize(Ty);
   bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
   if (IsEmpty || Size == 0) {
@@ -307,7 +311,6 @@ AArch64ABIInfo::classifyArgumentType(QualType Ty, bool 
IsVariadic,
 // 0.
 if (IsEmpty && Size == 0)
   return ABIArgInfo::getIgnore();
-return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
   }
 
   // Homogeneous Floating-point Aggregates (HFAs) need to be expanded.
diff --git a/clang/test/CodeGen/aarch64-args.cpp 
b/clang/test/CodeGen/aarch64-args.cpp
index fe1298cc683a404..709f916d7a677d1 100644
--- a/clang/test/CodeGen/aarch64-args.cpp
+++ b/clang/test/CodeGen/aarch64-args.cpp
@@ -17,7 +17,7 @@ struct Empty {};
 
 // CHECK: define{{.*}} i32 @empty_arg(i32 noundef %a)
 // CHECK-GNU-C: define{{.*}} i32 @empty_arg(i32 noundef %a)
-// CHECK-GNU-CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_arg(i64 %e.coerce, i32 noundef %a)
 EXTERNC int empty_arg(struct Empty e, int a) {
   return a;
 }
@@ -53,7 +53,7 @@ struct SortOfEmpty {
 
 // CHECK: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
 // CHECK-GNU-C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
-// CHECK-GNU-CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 
noundef %a)
+// CHECK-GNU-CXX: define{{.*}} i32 @sort_of_empty_arg(i64 %e.coerce, i32 
noundef %a)
 EXTERNC int sort_of_empty_arg(struct Empty e, int a) {
   return a;
 }
@@ -65,3 +65,22 @@ EXTERNC struct SortOfEmpty sort_of_empty_ret(void) {
   struct SortOfEmpty e;
   return e;
 }
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align8_arg(i64 %a.coerce, i32 
noundef %b)
+struct EmptyAlign8 { int __attribute__((aligned(8))) : 0; };
+EXTERNC int empty_align8_arg(struct EmptyAlign8 a, int b) {
+  return b;
+}
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align16_arg(i128 %a.coerce, i32 
noundef %b)
+struct EmptyAlign16 { long long int __attribute__((aligned(16))) : 0; };
+EXTERNC int empty_align16_arg(struct EmptyAlign16 a, int b) {
+  return b;
+}
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align32_arg(ptr noundef %a, i32 
noundef %b)
+struct EmptyAlign32 { long long int __attribute__((aligned(32))) : 0; };
+EXTERNC int empty_align32_arg(struct EmptyAlign32 a, int b) {
+  return b;
+}
+
diff --git a/clang/test/CodeGen/arm64-microsoft-arguments.cpp 
b/clang/test/CodeGen/arm64-microsoft-arguments.cpp
index a9ae6911b16e339..f7370e9f5351c5b 100644
--- a/clang/test/CodeGen/arm64-microsoft-arguments.cpp
+++ b/clang/test/CodeGen/arm64-microsoft-arguments.cpp
@@ -57,7 +57,7 @@ S4 f4() {
 
 // Pass and return from instance method called from instance method.
 // CHECK: define {{.*}} void @{{.*}}bar@Q1{{.*}}(ptr {{[^,]*}} %this, ptr 
inreg noalias sret(%class.P1) align 1 %agg.result)
-// CHECK: call void {{.*}}foo@P1{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr 
inreg sret(%class.P1) align 1 %agg.result, i8 %0)
+// CHECK: call void {{.*}}foo@P1{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr 
inreg sret(%class.P1) align 1 %agg.result, i64 %coerce.val.ii)
 
 class P1 {
 public:
@@ -76,7 +76,7 @@ P1 Q1::bar() {
 
 // Pass and return from instance method called from free function.
 // CHECK: define {{.*}} void {{.*}}bar{{.*}}()
-// CHECK: call void {{.*}}foo@P2{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr 
inreg sret(%class.P2) align 1 %retval, i8 %0)
+// CHECK: 

[clang] [clang] Accept lambdas in C++03 as an extensions (PR #73376)

2023-11-24 Thread via cfe-commits


@@ -1030,6 +1030,7 @@ def err_capture_default_first : Error<
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
   "is a C++23 extension">, InGroup;
+def ext_lambda : ExtWarn<"lambdas are a C++11 extension">, InGroup;

cor3ntin wrote:

This is not tested.  Also you probably want to move that next to 
warn_cxx98_compat_lambda

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


[clang] [clang] Fix sorting header paths (PR #73323)

2023-11-24 Thread David Blaikie via cfe-commits

dwblaikie wrote:

So what breakage is caused by the sorting failure? Can that behavior be tested 
in some way to validate this change and ensure it doesn't regress in the future?

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


[clang] [clang] Accept lambdas in C++03 as an extensions (PR #73376)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (philnik777)


Changes

This is a fairly simple extension, but makes the life for people who
have to support C++03 a lot easier. As a nice bonus, this also improves
diagnostics, since lambdas are now properly recognized when parsing
C++03 code.


---
Full diff: https://github.com/llvm/llvm-project/pull/73376.diff


5 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+1) 
- (modified) clang/lib/Parse/ParseExpr.cpp (+1-1) 
- (modified) clang/lib/Parse/ParseExprCXX.cpp (+3-1) 
- (modified) clang/lib/Parse/ParseInit.cpp (+1-1) 
- (modified) clang/test/Parser/cxx0x-lambda-expressions.cpp (+47-69) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index b66ecf0724b1c77..c8616cacda62280 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1030,6 +1030,7 @@ def err_capture_default_first : Error<
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
   "is a C++23 extension">, InGroup;
+def ext_lambda : ExtWarn<"lambdas are a C++11 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 897810557976151..c453d77329111f6 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1799,7 +1799,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind 
ParseKind,
 }
 goto ExpectedExpression;
   case tok::l_square:
-if (getLangOpts().CPlusPlus11) {
+if (getLangOpts().CPlusPlus) {
   if (getLangOpts().ObjC) {
 // C++11 lambda expressions and Objective-C message sends both start 
with a
 // square bracket.  There are three possibilities here:
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 79db094e098f8e6..9b459e8a4d3f4b2 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1271,7 +1271,9 @@ static void DiagnoseStaticSpecifierRestrictions(Parser ,
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
  LambdaIntroducer ) {
   SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
-  Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
+  Diag(LambdaBeginLoc, getLangOpts().CPlusPlus11
+   ? diag::warn_cxx98_compat_lambda
+   : diag::ext_lambda);
 
   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
 "lambda expression parsing");
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 637f21176792b6b..423497bfcb6621a 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -35,7 +35,7 @@ bool Parser::MayBeDesignationStart() {
 return true;
 
   case tok::l_square: {  // designator: array-designator
-if (!PP.getLangOpts().CPlusPlus11)
+if (!PP.getLangOpts().CPlusPlus)
   return true;
 
 // C++11 lambda expressions and C99 designators can be ambiguous all the
diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp 
b/clang/test/Parser/cxx0x-lambda-expressions.cpp
index 72b315a497c0679..a786a964163e4c4 100644
--- a/clang/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp
@@ -1,10 +1,15 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 
-Wno-c99-designator %s
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++20 
-Wno-c99-designator %s
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++23 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 
-Wno-c99-designator %s -Wno-c++11-extensions
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++11 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx17ext,cxx20ext,cxx23ext  -std=c++14 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx20ext,cxx23ext   -std=c++17 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx23ext   
 -std=c++20 -Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected
 -std=c++23 -Wno-c99-designator %s
 
 enum E { e };
 
+#if __cplusplus >= 201103L
 constexpr int id(int n) { return n; }
+#endif
 
 class C {
 
@@ -19,28 +24,25 @@ class C {
 [&,] {}; // expected-error {{expected variable name or 'this' in lambda 
capture list}}
 [=,] {}; // expected-error {{expected variable name 

[clang] [clang] Accept lambdas in C++03 as an extensions (PR #73376)

2023-11-24 Thread via cfe-commits

https://github.com/philnik777 created 
https://github.com/llvm/llvm-project/pull/73376

This is a fairly simple extension, but makes the life for people who
have to support C++03 a lot easier. As a nice bonus, this also improves
diagnostics, since lambdas are now properly recognized when parsing
C++03 code.


>From b08f0a6621fe50f5da564c4b4cbf8fae12778c12 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Sat, 25 Nov 2023 04:00:57 +0100
Subject: [PATCH] [clang] Accept lambdas in C++03 as an extensions

This is a fairly simple extension, but makes the life for people who
have to support C++03 a lot easier. As a nice bonus, this also improves
diagnostics, since lambdas are now properly recognized when parsing
C++03 code.
---
 .../clang/Basic/DiagnosticParseKinds.td   |   1 +
 clang/lib/Parse/ParseExpr.cpp |   2 +-
 clang/lib/Parse/ParseExprCXX.cpp  |   4 +-
 clang/lib/Parse/ParseInit.cpp |   2 +-
 .../test/Parser/cxx0x-lambda-expressions.cpp  | 116 +++---
 5 files changed, 53 insertions(+), 72 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index b66ecf0724b1c77..c8616cacda62280 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1030,6 +1030,7 @@ def err_capture_default_first : Error<
 def ext_decl_attrs_on_lambda : ExtWarn<
   "%select{an attribute specifier sequence|%0}1 in this position "
   "is a C++23 extension">, InGroup;
+def ext_lambda : ExtWarn<"lambdas are a C++11 extension">, InGroup;
 def ext_lambda_missing_parens : ExtWarn<
   "lambda without a parameter clause is a C++23 extension">,
   InGroup;
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 897810557976151..c453d77329111f6 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1799,7 +1799,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind 
ParseKind,
 }
 goto ExpectedExpression;
   case tok::l_square:
-if (getLangOpts().CPlusPlus11) {
+if (getLangOpts().CPlusPlus) {
   if (getLangOpts().ObjC) {
 // C++11 lambda expressions and Objective-C message sends both start 
with a
 // square bracket.  There are three possibilities here:
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 79db094e098f8e6..9b459e8a4d3f4b2 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1271,7 +1271,9 @@ static void DiagnoseStaticSpecifierRestrictions(Parser ,
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
  LambdaIntroducer ) {
   SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
-  Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda);
+  Diag(LambdaBeginLoc, getLangOpts().CPlusPlus11
+   ? diag::warn_cxx98_compat_lambda
+   : diag::ext_lambda);
 
   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
 "lambda expression parsing");
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 637f21176792b6b..423497bfcb6621a 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -35,7 +35,7 @@ bool Parser::MayBeDesignationStart() {
 return true;
 
   case tok::l_square: {  // designator: array-designator
-if (!PP.getLangOpts().CPlusPlus11)
+if (!PP.getLangOpts().CPlusPlus)
   return true;
 
 // C++11 lambda expressions and C99 designators can be ambiguous all the
diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp 
b/clang/test/Parser/cxx0x-lambda-expressions.cpp
index 72b315a497c0679..a786a964163e4c4 100644
--- a/clang/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp
@@ -1,10 +1,15 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 
-Wno-c99-designator %s
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++20 
-Wno-c99-designator %s
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++23 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 
-Wno-c99-designator %s -Wno-c++11-extensions
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++11 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx17ext,cxx20ext,cxx23ext  -std=c++14 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 
-verify=expected,cxx20ext,cxx23ext   -std=c++17 
-Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx23ext   
 -std=c++20 -Wno-c99-designator %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From 881d627cde823edded1c0fd1a72d9ffc2f4ee186 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 105 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 102 insertions(+), 28 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..17e742e1178df1d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool IsSingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  // Generddate a transition for the success state of `fputc`.
+  if (IsSingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = StateFailed->set(StreamSym, NewSS);
+  C.addTransition(StateFailed);
+}
+
 void StreamChecker::preFseek(const FnDescription *Desc, const CallEvent ,
  CheckerContext ) const {
   ProgramStateRef State = C.getState();
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index fc57e8bdc3d30c3..7ef5f29fbf42cb1 100644
--- 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From 2759d206be48d68dc93ed34efa782daf1097bb26 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 105 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 102 insertions(+), 28 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..919e620a58743e1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool SingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  // Generddate a transition for the success state of `fputc`.
+  if (SingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = StateFailed->set(StreamSym, NewSS);
+  C.addTransition(StateFailed);
+}
+
 void StreamChecker::preFseek(const FnDescription *Desc, const CallEvent ,
  CheckerContext ) const {
   ProgramStateRef State = C.getState();
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index fc57e8bdc3d30c3..7ef5f29fbf42cb1 100644
--- 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From 9a11834bb5a8d2c0aa97311541ca5a2b9848c859 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 109 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..b07709c4572ba0e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder  = C.getSValBuilder();
-auto  = C.getASTContext();
 // The returned 'unsigned char' of `fgetc` is converted to 'int',
 // so we need to check if it is in range [0, 255].
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
 auto CondLow =
 SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ASTC.IntTy),
   SVB.getConditionType())
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool SingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  // Generddate a transition for the success state of `fputc`.
+  if (SingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From efb399b878830899cdabc2fe0ee9d6fd398df259 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 109 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..6c0e675173bef55 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  if (OldSS->ErrorState != ErrorFEof) {
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder  = C.getSValBuilder();
-auto  = C.getASTContext();
 // The returned 'unsigned char' of `fgetc` is converted to 'int',
 // so we need to check if it is in range [0, 255].
 auto CondLow =
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool SingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  // Generddate a transition for the success state of `fputc`.
+  if (SingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+SValBuilder  = C.getSValBuilder();
+auto  = C.getASTContext();
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = StateFailed->set(StreamSym, NewSS);
+  C.addTransition(StateFailed);
+}
+
 void StreamChecker::preFseek(const FnDescription *Desc, 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From caa4a548adbab8532b6a3906e574eb9584914631 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 109 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..5e87f824cd780fa 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  SValBuilder  = C.getSValBuilder();
+  auto  = C.getASTContext();
+  if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder  = C.getSValBuilder();
-auto  = C.getASTContext();
 // The returned 'unsigned char' of `fgetc` is converted to 'int',
 // so we need to check if it is in range [0, 255].
 auto CondLow =
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool SingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  SValBuilder  = C.getSValBuilder();
+  auto  = C.getASTContext();
+  // Generddate a transition for the success state of `fputc`.
+  if (SingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = StateFailed->set(StreamSym, NewSS);
+  C.addTransition(StateFailed);
+}
+
 void StreamChecker::preFseek(const FnDescription *Desc, const 

[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 5ac5c0e7d1007745456329dbcf05aa15b50c08c8 
c015c1aa18e1048071dc59e637b7e20707b9ae83 -- 
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
clang/test/Analysis/Inputs/system-header-simulator.h 
clang/test/Analysis/stream-error.c clang/test/Analysis/stream.c
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index b5101f72f3..5e87f824cd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -761,7 +761,7 @@ void StreamChecker::evalFreadFwrite(const FnDescription 
*Desc,
 }
 
 void StreamChecker::evalFgetc(const FnDescription *Desc, const CallEvent ,
-   CheckerContext ) const {
+  CheckerContext ) const {
   ProgramStateRef State = C.getState();
   SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
   if (!StreamSym)

``




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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Ben Shi via cfe-commits

https://github.com/benshi001 updated 
https://github.com/llvm/llvm-project/pull/73335

>From c015c1aa18e1048071dc59e637b7e20707b9ae83 Mon Sep 17 00:00:00 2001
From: Ben Shi 
Date: Fri, 24 Nov 2023 22:51:27 +0800
Subject: [PATCH] [clang][analyzer] Support `fputs` in the StreamChecker

---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 109 +-
 .../Analysis/Inputs/system-header-simulator.h |   1 +
 clang/test/Analysis/stream-error.c|  18 +++
 clang/test/Analysis/stream.c  |   6 +
 4 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..b5101f72f316a0e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,13 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
-  }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
-  else if (OldSS->ErrorState != ErrorFEof) {
+  SValBuilder  = C.getSValBuilder();
+  auto  = C.getASTContext();
+  if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder  = C.getSValBuilder();
-auto  = C.getASTContext();
 // The returned 'unsigned char' of `fgetc` is converted to 'int',
 // so we need to check if it is in range [0, 255].
 auto CondLow =
@@ -824,20 +817,76 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // If a (non-EOF) error occurs, the resulting value of the file position
   // indicator for the stream is indeterminate.
-  StreamErrorState NewES;
-  if (IsRead)
-NewES =
-OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
-  else
-NewES = ErrorFError;
+  StreamErrorState NewES =
+  OldSS->ErrorState == ErrorFEof ? ErrorFEof : ErrorFEof | ErrorFError;
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set(StreamSym, NewSS);
-  if (IsRead && OldSS->ErrorState != ErrorFEof)
+  if (OldSS->ErrorState != ErrorFEof)
 C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
   else
 C.addTransition(StateFailed);
 }
 
+void StreamChecker::evalFputx(const FnDescription *Desc, const CallEvent ,
+  CheckerContext , bool SingleChar) const {
+  ProgramStateRef State = C.getState();
+  SymbolRef StreamSym = getStreamArg(Desc, Call).getAsSymbol();
+  if (!StreamSym)
+return;
+
+  const CallExpr *CE = dyn_cast_or_null(Call.getOriginExpr());
+  if (!CE)
+return;
+
+  const StreamState *OldSS = State->get(StreamSym);
+  if (!OldSS)
+return;
+
+  assertStreamStateOpened(OldSS);
+
+  // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
+
+  SValBuilder  = C.getSValBuilder();
+  auto  = C.getASTContext();
+  // Generddate a transition for the success state of `fputc`.
+  if (SingleChar) {
+std::optional PutVal = Call.getArgSVal(0).getAs();
+if (!PutVal)
+  return;
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), *PutVal);
+StateNotFailed =
+StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
+C.addTransition(StateNotFailed);
+  }
+  // Generddate a transition for the success state of `fputs`.
+  else {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+ProgramStateRef StateNotFailed =
+State->BindExpr(CE, C.getLocationContext(), RetVal);
+auto Cond = SVB.evalBinOp(State, BO_GE, RetVal, 
SVB.makeZeroVal(ASTC.IntTy),
+  SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return;
+StateNotFailed = StateNotFailed->assume(*Cond, true);
+if (!StateNotFailed)
+  return;
+C.addTransition(StateNotFailed);
+  }
+
+  // Add transition for the failed state.
+  ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+
+  // If a (non-EOF) error occurs, the resulting value of the file position
+  // indicator for the stream is indeterminate.
+  StreamErrorState NewES = ErrorFError;
+  StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
+  StateFailed = StateFailed->set(StreamSym, NewSS);
+  C.addTransition(StateFailed);
+}
+
 void StreamChecker::preFseek(const FnDescription *Desc, const 

[clang] [clang-format] Fix a bug in formating `#define A x:` (PR #73220)

2023-11-24 Thread Owen Pan via cfe-commits


@@ -1171,6 +1171,13 @@ void UnwrappedLineParser::parsePPDefine() {
   assert((int)Line->PPLevel >= 0);
   Line->InMacroBody = true;
 
+  if (FormatTok->is(tok::identifier) &&
+  Tokens->peekNextToken()->is(tok::colon)) {
+nextToken();
+nextToken();
+addUnwrappedLine();

owenca wrote:

Good catch!

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


[clang] [clang-format] Fix a bug in formating `#define A x:` (PR #73220)

2023-11-24 Thread Owen Pan via cfe-commits

https://github.com/owenca updated 
https://github.com/llvm/llvm-project/pull/73220

>From 0a8459053be654313efff8002ff3e171d8cd9d18 Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Thu, 23 Nov 2023 00:41:41 -0800
Subject: [PATCH 1/2] [clang-format] Fix a bug in formating `#define A x:`

Fixed #70789.
---
 clang/lib/Format/UnwrappedLineParser.cpp | 7 +++
 clang/unittests/Format/FormatTest.cpp| 2 ++
 2 files changed, 9 insertions(+)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index c870ff01605e725..0f841e0bee50b6c 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1171,6 +1171,13 @@ void UnwrappedLineParser::parsePPDefine() {
   assert((int)Line->PPLevel >= 0);
   Line->InMacroBody = true;
 
+  if (FormatTok->is(tok::identifier) &&
+  Tokens->peekNextToken()->is(tok::colon)) {
+nextToken();
+nextToken();
+addUnwrappedLine();
+  }
+
   // Errors during a preprocessor directive can only affect the layout of the
   // preprocessor directive, and thus we ignore them. An alternative approach
   // would be to use the same approach we use on the file level (no
diff --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 67423f9b06fbc37..d095a2b751defe3 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -1863,6 +1863,8 @@ TEST_F(FormatTest, UnderstandsMacros) {
   verifyFormat("MACRO(something##something)");
   verifyFormat("MACRO(return##something)");
   verifyFormat("MACRO(co_return##something)");
+
+  verifyFormat("#define A x:");
 }
 
 TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) {

>From f42867e3129cb31568c5a69b89da9d927554f3fb Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Fri, 24 Nov 2023 16:55:11 -0800
Subject: [PATCH 2/2] Removed the unneeded addUnwrappedLine() call.

---
 clang/lib/Format/UnwrappedLineParser.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 0f841e0bee50b6c..7b4ec25a8938fc0 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1175,7 +1175,6 @@ void UnwrappedLineParser::parsePPDefine() {
   Tokens->peekNextToken()->is(tok::colon)) {
 nextToken();
 nextToken();
-addUnwrappedLine();
   }
 
   // Errors during a preprocessor directive can only affect the layout of the

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Youngsuk Kim via cfe-commits

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


[clang] bc85284 - [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (#73374)

2023-11-24 Thread via cfe-commits

Author: Youngsuk Kim
Date: 2023-11-24T19:22:02-05:00
New Revision: bc85284273ea1e6efbf7367f736f7982459c652b

URL: 
https://github.com/llvm/llvm-project/commit/bc85284273ea1e6efbf7367f736f7982459c652b
DIFF: 
https://github.com/llvm/llvm-project/commit/bc85284273ea1e6efbf7367f736f7982459c652b.diff

LOG: [clang-linker-wrapper] Re-use type returned from 
'PointerType::getUnqual(C)' (NFC) (#73374)

Multiple calls to `PointerType::getUnqual(C)`, and calls to
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function
`createRegisterGlobalsFunction()`.

Added: 


Modified: 
clang/tools/clang-linker-wrapper/OffloadWrapper.cpp

Removed: 




diff  --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 4bbfba777e1854f..3e1dd874216ccf3 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -457,45 +457,41 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
IsHIP ? ".hip.fatbin_unreg" : ".cuda.fatbin_unreg", );
   DtorFunc->setSection(".text.startup");
 
+  auto *PtrTy = PointerType::getUnqual(C);
+
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
- /*isVarArg*/ false);
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy, /*isVarArg=*/false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
-  auto *RegFatEndTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *RegFatEndTy =
+  FunctionType::get(Type::getVoidTy(C), PtrTy, /*isVarArg=*/false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
-  auto *UnregFatTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *UnregFatTy =
+  FunctionType::get(Type::getVoidTy(C), PtrTy, /*isVarArg=*/false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
   auto *AtExitTy =
-  FunctionType::get(Type::getInt32Ty(C), DtorFuncTy->getPointerTo(),
-/*isVarArg*/ false);
+  FunctionType::get(Type::getInt32Ty(C), PtrTy, /*isVarArg=*/false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(
-  M, PointerType::getUnqual(C)->getPointerTo(), false,
-  llvm::GlobalValue::InternalLinkage,
-  
llvm::ConstantPointerNull::get(PointerType::getUnqual(C)->getPointerTo()),
+  M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+  llvm::ConstantPointerNull::get(PtrTy),
   IsHIP ? ".hip.binary_handle" : ".cuda.binary_handle");
 
   // Create the constructor to register this image with the runtime.
   IRBuilder<> CtorBuilder(BasicBlock::Create(C, "entry", CtorFunc));
   CallInst *Handle = CtorBuilder.CreateCall(
-  RegFatbin, ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- FatbinDesc, PointerType::getUnqual(C)));
+  RegFatbin,
+  ConstantExpr::getPointerBitCastOrAddrSpaceCast(FatbinDesc, PtrTy));
   CtorBuilder.CreateAlignedStore(
   Handle, BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP), Handle);
   if (!IsHIP)
 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
@@ -507,8 +503,8 @@ void createRegisterFatbinFunction(Module , GlobalVariable 
*FatbinDesc,
   // `atexit()` intead.
   IRBuilder<> DtorBuilder(BasicBlock::Create(C, "entry", DtorFunc));
   LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
-  PointerType::getUnqual(C)->getPointerTo(), BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  PtrTy, BinaryHandleGlobal,
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
   DtorBuilder.CreateRetVoid();
 



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


[clang] 1a3b14d - [RISCV] Add C intrinsics for scalar bitmanip and crypto

2023-11-24 Thread Craig Topper via cfe-commits

Author: Craig Topper
Date: 2023-11-24T16:17:22-08:00
New Revision: 1a3b14d26152ab7e7352c8e7aa97ec880cdac82d

URL: 
https://github.com/llvm/llvm-project/commit/1a3b14d26152ab7e7352c8e7aa97ec880cdac82d
DIFF: 
https://github.com/llvm/llvm-project/commit/1a3b14d26152ab7e7352c8e7aa97ec880cdac82d.diff

LOG: [RISCV] Add C intrinsics for scalar bitmanip and crypto

This adds riscv_bitmanip and riscv_crypto.h

This is based on the proposed spec here 
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/44

Tests that previously used builtins directly now use the intrinsics.

Reviewed By: wangpc

Differential Revision: https://reviews.llvm.org/D155647

Added: 
clang/lib/Headers/riscv_bitmanip.h
clang/lib/Headers/riscv_crypto.h

Modified: 
clang/lib/Headers/CMakeLists.txt
clang/test/CodeGen/RISCV/rvb-intrinsics/zbkb.c
clang/test/CodeGen/RISCV/rvb-intrinsics/zbkc.c
clang/test/CodeGen/RISCV/rvb-intrinsics/zbkx.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv32-zknd.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv32-zkne.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv32-zknh.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv64-zknd-zkne.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv64-zknd.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv64-zkne.c
clang/test/CodeGen/RISCV/rvk-intrinsics/riscv64-zknh.c
clang/test/CodeGen/RISCV/rvk-intrinsics/zksed.c
clang/test/CodeGen/RISCV/rvk-intrinsics/zksh.c
llvm/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/lib/Headers/CMakeLists.txt 
b/clang/lib/Headers/CMakeLists.txt
index 8b1e2bc4afa4dcd..fdd54c05eedf825 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -116,6 +116,8 @@ set(ppc_htm_files
   )
 
 set(riscv_files
+  riscv_bitmanip.h
+  riscv_crypto.h
   riscv_ntlh.h
   sifive_vector.h
   )

diff  --git a/clang/lib/Headers/riscv_bitmanip.h 
b/clang/lib/Headers/riscv_bitmanip.h
new file mode 100644
index 000..1a81cc8618c9756
--- /dev/null
+++ b/clang/lib/Headers/riscv_bitmanip.h
@@ -0,0 +1,179 @@
+/*=== riscv_bitmanip.h - RISC-V Zb* intrinsics 
--===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===---===
+ */
+
+#ifndef __RISCV_BITMANIP_H
+#define __RISCV_BITMANIP_H
+
+#include 
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__riscv_zbb)
+static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
+__riscv_orc_b_32(uint32_t __x) {
+  return __builtin_riscv_orc_b_32(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_clz_32(uint32_t __x) {
+  return __builtin_riscv_clz_32(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_ctz_32(uint32_t __x) {
+  return __builtin_riscv_ctz_32(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_cpop_32(uint32_t __x) {
+  return __builtin_riscv_cpop_32(__x);
+}
+
+#if __riscv_xlen == 64
+static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
+__riscv_orc_b_64(uint64_t __x) {
+  return __builtin_riscv_orc_b_64(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_clz_64(uint64_t __x) {
+  return __builtin_riscv_clz_64(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_ctz_64(uint64_t __x) {
+  return __builtin_riscv_ctz_64(__x);
+}
+
+static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
+__riscv_cpop_64(uint64_t __x) {
+  return __builtin_riscv_cpop_64(__x);
+}
+#endif
+#endif // defined(__riscv_zbb)
+
+#if defined(__riscv_zbb) || defined(__riscv_zbkb)
+static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
+__riscv_rev8_32(uint32_t __x) {
+  return __builtin_bswap32(__x);
+}
+
+static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
+__riscv_rol_32(uint32_t __x, uint32_t __y) {
+  return __builtin_rotateleft32(__x, __y);
+}
+
+static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
+__riscv_ror_32(uint32_t __x, uint32_t __y) {
+  return __builtin_rotateright32(__x, __y);
+}
+
+#if __riscv_xlen == 64
+static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
+__riscv_rev8_64(uint64_t __x) {
+  return __builtin_bswap64(__x);
+}
+
+static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
+__riscv_rol_64(uint64_t __x, uint32_t __y) {
+  return __builtin_rotateleft64(__x, __y);
+}
+
+static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
+__riscv_ror_64(uint64_t __x, uint32_t __y) {
+  return 

[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Piotr Zegar via cfe-commits


@@ -658,27 +658,27 @@ void check_match_co_return() {
   co_return 1;
 }
 )cpp";
-  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
-   coreturnStmt(isExpansionInMainFile()), 
-   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoReturnCode,
+   coreturnStmt(isExpansionInMainFile()), true,

PiotrZSL wrote:

no need for, I will check tests tomorrow.

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Joseph Huber via cfe-commits

https://github.com/jhuber6 approved this pull request.

Thanks, this was never properly cleaned up after moving to opaque pointers.

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Youngsuk Kim via cfe-commits

https://github.com/JOE1994 updated 
https://github.com/llvm/llvm-project/pull/73374

>From cd36ba2c52f14051cbe82efc6390a036f75d2b46 Mon Sep 17 00:00:00 2001
From: Youngsuk Kim 
Date: Thu, 23 Nov 2023 10:54:07 -0600
Subject: [PATCH 1/3] [clang-linker-wrapper] Re-use type returned from
 'PointerType::getUnqual(C)' (NFC)

Multiple calls to `PointerType::getUnqual(C)`, and calls to
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function
`createRegisterGlobalsFunction()`.
---
 .../clang-linker-wrapper/OffloadWrapper.cpp   | 34 ---
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 4bbfba777e1854f..5daa7c083b564e0 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -445,6 +445,7 @@ Function *createRegisterGlobalsFunction(Module , bool 
IsHIP) {
 void createRegisterFatbinFunction(Module , GlobalVariable *FatbinDesc,
   bool IsHIP) {
   LLVMContext  = M.getContext();
+  auto *PtrTy = PointerType::getUnqual(C);
   auto *CtorFuncTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg*/ false);
   auto *CtorFunc =
   Function::Create(CtorFuncTy, GlobalValue::InternalLinkage,
@@ -458,44 +459,39 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
   DtorFunc->setSection(".text.startup");
 
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
  /*isVarArg*/ false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
-  auto *RegFatEndTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *RegFatEndTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+/*isVarArg*/ false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
-  auto *UnregFatTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *UnregFatTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+   /*isVarArg*/ false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
-  auto *AtExitTy =
-  FunctionType::get(Type::getInt32Ty(C), DtorFuncTy->getPointerTo(),
-/*isVarArg*/ false);
+  auto *AtExitTy = FunctionType::get(Type::getInt32Ty(C), PtrTy,
+ /*isVarArg*/ false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(
-  M, PointerType::getUnqual(C)->getPointerTo(), false,
-  llvm::GlobalValue::InternalLinkage,
-  
llvm::ConstantPointerNull::get(PointerType::getUnqual(C)->getPointerTo()),
+  M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+  llvm::ConstantPointerNull::get(PtrTy),
   IsHIP ? ".hip.binary_handle" : ".cuda.binary_handle");
 
   // Create the constructor to register this image with the runtime.
   IRBuilder<> CtorBuilder(BasicBlock::Create(C, "entry", CtorFunc));
   CallInst *Handle = CtorBuilder.CreateCall(
-  RegFatbin, ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- FatbinDesc, PointerType::getUnqual(C)));
+  RegFatbin,
+  ConstantExpr::getPointerBitCastOrAddrSpaceCast(FatbinDesc, PtrTy));
   CtorBuilder.CreateAlignedStore(
   Handle, BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP), Handle);
   if (!IsHIP)
 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
@@ -507,8 +503,8 @@ void createRegisterFatbinFunction(Module , GlobalVariable 
*FatbinDesc,
   // `atexit()` intead.
   IRBuilder<> DtorBuilder(BasicBlock::Create(C, "entry", DtorFunc));
   LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
-  PointerType::getUnqual(C)->getPointerTo(), BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  PtrTy, BinaryHandleGlobal,
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
   

[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Joseph Huber via cfe-commits


@@ -457,45 +457,42 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
IsHIP ? ".hip.fatbin_unreg" : ".cuda.fatbin_unreg", );
   DtorFunc->setSection(".text.startup");
 
+  auto *PtrTy = PointerType::getUnqual(C);
+
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
- /*isVarArg*/ false);
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
+ /*isVarArg=*/ false);

jhuber6 wrote:

Shouldn't clang-format remove the whitespace here? Figure it would come out 
looking like this but I think it's sometimes weird handling these types of 
arguments.
```suggestion
  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy, /*isVarArg=*/false);
```

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 12563ea6403f6f5a467862732b92db3517626cd2 
3d46f90bc8cf5d94ea5adae80bc9c96e11958b32 -- 
clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 398f34de53..fa313706c8 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -461,23 +461,23 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
 
   // Get the __cudaRegisterFatBinary function declaration.
   auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
- /*isVarArg=*/ false);
+ /*isVarArg=*/false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
   auto *RegFatEndTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
-/*isVarArg=*/ false);
+/*isVarArg=*/false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
   auto *UnregFatTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
-   /*isVarArg=*/ false);
+   /*isVarArg=*/false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
   auto *AtExitTy = FunctionType::get(Type::getInt32Ty(C), PtrTy,
- /*isVarArg=*/ false);
+ /*isVarArg=*/false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(

``




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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Youngsuk Kim via cfe-commits

https://github.com/JOE1994 updated 
https://github.com/llvm/llvm-project/pull/73374

>From cd36ba2c52f14051cbe82efc6390a036f75d2b46 Mon Sep 17 00:00:00 2001
From: Youngsuk Kim 
Date: Thu, 23 Nov 2023 10:54:07 -0600
Subject: [PATCH 1/2] [clang-linker-wrapper] Re-use type returned from
 'PointerType::getUnqual(C)' (NFC)

Multiple calls to `PointerType::getUnqual(C)`, and calls to
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function
`createRegisterGlobalsFunction()`.
---
 .../clang-linker-wrapper/OffloadWrapper.cpp   | 34 ---
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 4bbfba777e1854f..5daa7c083b564e0 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -445,6 +445,7 @@ Function *createRegisterGlobalsFunction(Module , bool 
IsHIP) {
 void createRegisterFatbinFunction(Module , GlobalVariable *FatbinDesc,
   bool IsHIP) {
   LLVMContext  = M.getContext();
+  auto *PtrTy = PointerType::getUnqual(C);
   auto *CtorFuncTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg*/ false);
   auto *CtorFunc =
   Function::Create(CtorFuncTy, GlobalValue::InternalLinkage,
@@ -458,44 +459,39 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
   DtorFunc->setSection(".text.startup");
 
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
  /*isVarArg*/ false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
-  auto *RegFatEndTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *RegFatEndTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+/*isVarArg*/ false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
-  auto *UnregFatTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *UnregFatTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+   /*isVarArg*/ false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
-  auto *AtExitTy =
-  FunctionType::get(Type::getInt32Ty(C), DtorFuncTy->getPointerTo(),
-/*isVarArg*/ false);
+  auto *AtExitTy = FunctionType::get(Type::getInt32Ty(C), PtrTy,
+ /*isVarArg*/ false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(
-  M, PointerType::getUnqual(C)->getPointerTo(), false,
-  llvm::GlobalValue::InternalLinkage,
-  
llvm::ConstantPointerNull::get(PointerType::getUnqual(C)->getPointerTo()),
+  M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+  llvm::ConstantPointerNull::get(PtrTy),
   IsHIP ? ".hip.binary_handle" : ".cuda.binary_handle");
 
   // Create the constructor to register this image with the runtime.
   IRBuilder<> CtorBuilder(BasicBlock::Create(C, "entry", CtorFunc));
   CallInst *Handle = CtorBuilder.CreateCall(
-  RegFatbin, ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- FatbinDesc, PointerType::getUnqual(C)));
+  RegFatbin,
+  ConstantExpr::getPointerBitCastOrAddrSpaceCast(FatbinDesc, PtrTy));
   CtorBuilder.CreateAlignedStore(
   Handle, BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP), Handle);
   if (!IsHIP)
 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
@@ -507,8 +503,8 @@ void createRegisterFatbinFunction(Module , GlobalVariable 
*FatbinDesc,
   // `atexit()` intead.
   IRBuilder<> DtorBuilder(BasicBlock::Create(C, "entry", DtorFunc));
   LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
-  PointerType::getUnqual(C)->getPointerTo(), BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  PtrTy, BinaryHandleGlobal,
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
   

[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits


@@ -658,27 +658,27 @@ void check_match_co_return() {
   co_return 1;
 }
 )cpp";
-  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
-   coreturnStmt(isExpansionInMainFile()), 
-   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoReturnCode,
+   coreturnStmt(isExpansionInMainFile()), true,

5chmidti wrote:

It looks like these formatting changes finally slipped through. Should I remove 
them from this patch?

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Julian Schmidt (5chmidti)


Changes

Adds support for the following matchers related to `CXXFoldExpr`: 
`cxxFoldExpr`, `callee`,
  `hasInit`, `hasPattern`, `isRightFold`, `isLeftFold`,
  `isUnaryFold`, `isBinaryFold`, `hasOperator`, `hasLHS`, `hasRHS`.

---

Patch is 54.96 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/71245.diff


10 Files Affected:

- (modified) clang/docs/LibASTMatchersReference.html (+271-23) 
- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+180-21) 
- (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+3) 
- (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+1) 
- (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+7) 
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+10-17) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (+93-6) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (+13) 
- (modified) clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (+149-9) 


``diff
diff --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index fcd3114bb523105..c40d679e383bb2a 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1629,6 +1629,17 @@ Node Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxFoldExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExpr...
+Matches C++17 fold 
expressions.
+
+Example matches `(0 + ... + args)`:
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxForRangeStmtMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html;>CXXForRangeStmt...
 Matches range-based 
for statements.
 
@@ -2965,11 +2976,18 @@ Narrowing Matchers
 
 
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html;>BinaryOperatorhasOperatorNamestd::string 
Name
-Matches the 
operator Name of operator expressions (binary or
-unary).
+Matches the 
operator Name of operator expressions and fold expressions
+(binary or unary).
 
 Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
   !(a || b)
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(hasOperatorName("+")))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
 
 
 
@@ -3430,6 +3448,91 @@ Narrowing Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprhasOperatorNamestd::string 
Name
+Matches the 
operator Name of operator expressions and fold expressions
+(binary or unary).
+
+Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+  !(a || b)
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(hasOperatorName("+")))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisBinaryFold
+Matches binary fold 
expressions, i.e. fold expressions with an initializer.
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(isBinaryFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ...);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisLeftFold
+Matches left-folding 
fold expressions.
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(isLeftFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisRightFold
+Matches right-folding 
fold expressions.
+
+Example matches `(args * ... * 1)`
+(matcher = cxxFoldExpr(isRightFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisUnaryFold
+Matches unary fold 
expressions, i.e. fold expressions without an
+initializer.
+
+Example matches `(args * ...)`
+(matcher = cxxFoldExpr(isUnaryFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ...);
+  }
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html;>CXXMethodDeclisConst
 Matches if the given method 
declaration is 

[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits


@@ -4532,6 +4563,139 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
   return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
 }
 
+/// Matches the operand that does not contain the parameter pack.
+///
+/// Example matches `(0 + ... + args)` and `(args * ... * 1)`
+/// (matcher = cxxFoldExpr(hasFoldInit(expr(
+///   with hasFoldInit(...)
+/// matching `0` and `1` respectively
+/// \code
+///   template 
+///   auto sum(Args... args) {
+///   return (0 + ... + args);
+///   }
+///
+///   template 
+///   auto multiply(Args... args) {
+///   return (args * ... * 1);
+///   }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher,
+  InnerMacher) {
+  const auto *const Init = Node.getInit();
+  return Init && InnerMacher.matches(*Init, Finder, Builder);
+}
+
+/// Matches the operand that contains the parameter pack.
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(hasPattern(expr(
+///   with hasPattern(...)
+/// matching `args`
+/// \code
+///   template 
+///   auto sum(Args... args) {
+///   return (0 + ... + args);
+///   }
+///
+///   template 
+///   auto multiply(Args... args) {
+///   return (args * ... * 1);
+///   }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher,
+  InnerMacher) {
+  return InnerMacher.matches(*Node.getPattern(), Finder, Builder);

5chmidti wrote:

done

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits


@@ -319,6 +319,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasExplicitSpecifier);
   REGISTER_MATCHER(hasExternalFormalLinkage);
   REGISTER_MATCHER(hasFalseExpression);
+  REGISTER_MATCHER(hasFoldInit);

5chmidti wrote:

done

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits

5chmidti wrote:

> Pull request doesn't say anything.

Fixed, I just listed the matchers that were added/adjusted for `CXXFoldExpr` 
support.

> Whats a purpose of those matchers (except only to have them).

Sorry, forgot to add that comment. I didn't want that to be part of the pr 
description (because of the squashed commit message), or should it?
My fix for #70323 uses `cxxFoldExpr` and `hasFoldInit`. `ASTImporterTest.cpp` 
already defined matchers for fold expressions, which is why I thought that they 
could be part of the public matchers. If that is not enough to warrant adding 
these matchers to the publically available ones, I can just implement those two 
matchers in `ExprMutationAnalyzer.cpp`.

> Someone said not so long ago that we do not want to add matchers unless there 
> is some usecase for them in some of the tools.

I think I read the same comment, but I don't know who said that and where.

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


[clang] afe8b93 - [clang] Avoid memcopy for small structure with padding under -ftrivial-auto-var-init (#71677)

2023-11-24 Thread via cfe-commits

Author: serge-sans-paille
Date: 2023-11-25T00:11:20+01:00
New Revision: afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d

URL: 
https://github.com/llvm/llvm-project/commit/afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d
DIFF: 
https://github.com/llvm/llvm-project/commit/afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d.diff

LOG: [clang] Avoid memcopy for small structure with padding under 
-ftrivial-auto-var-init (#71677)

Recommit of 0d2860b795879f4dd152963b52f969b53b136899 with extra test
cases fixed.

Added: 


Modified: 
clang/lib/CodeGen/CGDecl.cpp
clang/test/CodeGen/aapcs-align.cpp
clang/test/CodeGen/aapcs64-align.cpp
clang/test/CodeGenCXX/auto-var-init.cpp
clang/test/CodeGenOpenCL/amdgpu-printf.cl
clang/test/OpenMP/bug54082.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index e5795d811c76de7..a5da0aa2965a000 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1244,29 +1244,24 @@ static void emitStoresForConstant(CodeGenModule , 
const VarDecl ,
   // If the initializer is small, use a handful of stores.
   if (shouldSplitConstantStore(CGM, ConstantSize)) {
 if (auto *STy = dyn_cast(Ty)) {
-  // FIXME: handle the case when STy != Loc.getElementType().
-  if (STy == Loc.getElementType()) {
-for (unsigned i = 0; i != constant->getNumOperands(); i++) {
-  Address EltPtr = Builder.CreateStructGEP(Loc, i);
-  emitStoresForConstant(
-  CGM, D, EltPtr, isVolatile, Builder,
-  cast(Builder.CreateExtractValue(constant, i)),
-  IsAutoInit);
-}
-return;
+  const llvm::StructLayout *Layout =
+  CGM.getDataLayout().getStructLayout(STy);
+  for (unsigned i = 0; i != constant->getNumOperands(); i++) {
+CharUnits CurOff = 
CharUnits::fromQuantity(Layout->getElementOffset(i));
+Address EltPtr = Builder.CreateConstInBoundsByteGEP(
+Loc.withElementType(CGM.Int8Ty), CurOff);
+emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+  constant->getAggregateElement(i), IsAutoInit);
   }
+  return;
 } else if (auto *ATy = dyn_cast(Ty)) {
-  // FIXME: handle the case when ATy != Loc.getElementType().
-  if (ATy == Loc.getElementType()) {
-for (unsigned i = 0; i != ATy->getNumElements(); i++) {
-  Address EltPtr = Builder.CreateConstArrayGEP(Loc, i);
-  emitStoresForConstant(
-  CGM, D, EltPtr, isVolatile, Builder,
-  cast(Builder.CreateExtractValue(constant, i)),
-  IsAutoInit);
-}
-return;
+  for (unsigned i = 0; i != ATy->getNumElements(); i++) {
+Address EltPtr = Builder.CreateConstGEP(
+Loc.withElementType(ATy->getElementType()), i);
+emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+  constant->getAggregateElement(i), IsAutoInit);
   }
+  return;
 }
   }
 

diff  --git a/clang/test/CodeGen/aapcs-align.cpp 
b/clang/test/CodeGen/aapcs-align.cpp
index 4f393d9e6b7f320..2886a32974b0665 100644
--- a/clang/test/CodeGen/aapcs-align.cpp
+++ b/clang/test/CodeGen/aapcs-align.cpp
@@ -134,8 +134,8 @@ void g6() {
   f6m(1, 2, 3, 4, 5, s);
 }
 // CHECK: define{{.*}} void @g6
-// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 
undef])
-// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 
noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef])
+// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 
noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
 // CHECK: declare void @f6(i32 noundef, [4 x i32])
 // CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 
noundef, i32 noundef, [4 x i32])
 }

diff  --git a/clang/test/CodeGen/aapcs64-align.cpp 
b/clang/test/CodeGen/aapcs64-align.cpp
index de231f2123b9755..759413cbc4b56f6 100644
--- a/clang/test/CodeGen/aapcs64-align.cpp
+++ b/clang/test/CodeGen/aapcs64-align.cpp
@@ -75,8 +75,8 @@ void g4() {
   f4m(1, 2, 3, 4, 5, s);
 }
 // CHECK: define{{.*}} void @g4()
-// CHECK: call void @f4(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0])
-// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 
4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0])
+// CHECK: call void @f4(i32 noundef 1, [2 x i64] %{{.*}})
+// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 
4, i32 noundef 5, [2 x i64] %{{.*}})
 // CHECK: declare void @f4(i32 noundef, [2 x i64])
 // CHECK: declare void @f4m(i32 noundef, i32 noundef, i32 noundef, i32 
noundef, i32 noundef, [2 x i64])
 
@@ -95,8 +95,8 @@ void f5m(int, int, int, int, int, P16);
 f5m(1, 2, 3, 4, 5, s);
 }
 // CHECK: 

[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits

https://github.com/5chmidti updated 
https://github.com/llvm/llvm-project/pull/71245

>From ae352f244a031b587d136423e0e3ef51f522c771 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com>
Date: Fri, 3 Nov 2023 21:51:57 +0100
Subject: [PATCH 1/5] [clang][ASTMatcher] Add matchers for CXXFoldExpr

---
 clang/docs/LibASTMatchersReference.html   | 209 +-
 clang/docs/ReleaseNotes.rst   |   3 +
 clang/include/clang/ASTMatchers/ASTMatchers.h | 194 ++--
 clang/lib/ASTMatchers/ASTMatchersInternal.cpp |   1 +
 clang/lib/ASTMatchers/Dynamic/Registry.cpp|   1 +
 clang/unittests/AST/ASTImporterTest.cpp   |  27 +--
 .../ASTMatchers/ASTMatchersNarrowingTest.cpp  |  99 -
 .../ASTMatchers/ASTMatchersNodeTest.cpp   |  13 ++
 .../ASTMatchers/ASTMatchersTraversalTest.cpp  |  89 
 9 files changed, 594 insertions(+), 42 deletions(-)

diff --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index fcd3114bb523105..39d1ffe3d2dee3b 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1629,6 +1629,17 @@ Node Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxFoldExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExpr...
+Matches C++17 fold 
expressions.
+
+Example matches `(0 + ... + args)`:
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxForRangeStmtMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html;>CXXForRangeStmt...
 Matches range-based 
for statements.
 
@@ -3430,6 +3441,92 @@ Narrowing Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprhasOperatorBinaryOperatorKind 
Op
+Matches the operator 
kind of the fold expression.
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(hasOperator(BO_Add)))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisBinaryFold
+Matches binary fold 
expressions, i.e. fold expressions with an initializer.
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(isBinaryFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ...);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisLeftFold
+Matches left-folding 
fold expressions.
+
+Example matches `(0 + ... + args)`
+(matcher = cxxFoldExpr(isLeftFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisRightFold
+Matches right-folding 
fold expressions.
+
+Example matches `(args * ... * 1)`
+(matcher = cxxFoldExpr(isRightFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprisUnaryFold
+Matches unary fold 
expressions, i.e. fold expressions without an
+initializer.
+
+Example matches `(args * ...)`
+(matcher = cxxFoldExpr(isUnaryFold()))
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ...);
+  }
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html;>CXXMethodDeclisConst
 Matches if the given method 
declaration is const.
 
@@ -6885,6 +6982,93 @@ AST Traversal Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html;>CXXFoldExprcalleeMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>Stmt 
InnerMatcher
+Matches if the call or fold 
expression's callee expression matches.
+
+Given
+  class Y { void x() { this-x(); x(); Y y; y.x(); } };
+  void f() { f(); }
+callExpr(callee(expr()))
+  matches this-x(), x(), y.x(), f()
+with callee(...)
+  matching this-x, x, y.x, f respectively
+
+Given
+  template typename... Args
+  auto sum(Args... args) {
+  return (0 + ... + args);
+  }
+
+  template typename... Args
+  auto multiply(Args... args) {
+  return (args * ... * 1);
+  }
+cxxFoldExpr(callee(expr()))
+  matches (args * ... * 1)
+with callee(...)
+  matching *
+
+Note: Callee cannot take the more general 

[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Joseph Huber via cfe-commits

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Joseph Huber via cfe-commits


@@ -458,44 +459,39 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
   DtorFunc->setSection(".text.startup");
 
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
  /*isVarArg*/ false);

jhuber6 wrote:

Can you fix these while you're at it, they should use the LLVM-style block 
comments.
```suggestion
 /*isVarArg=*/false);
```

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


[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Youngsuk Kim (JOE1994)


Changes

Multiple calls to `PointerType::getUnqual(C)`, and calls to 
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function 
`createRegisterGlobalsFunction()`.

---
Full diff: https://github.com/llvm/llvm-project/pull/73374.diff


1 Files Affected:

- (modified) clang/tools/clang-linker-wrapper/OffloadWrapper.cpp (+15-19) 


``diff
diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 4bbfba777e1854f..5daa7c083b564e0 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -445,6 +445,7 @@ Function *createRegisterGlobalsFunction(Module , bool 
IsHIP) {
 void createRegisterFatbinFunction(Module , GlobalVariable *FatbinDesc,
   bool IsHIP) {
   LLVMContext  = M.getContext();
+  auto *PtrTy = PointerType::getUnqual(C);
   auto *CtorFuncTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg*/ false);
   auto *CtorFunc =
   Function::Create(CtorFuncTy, GlobalValue::InternalLinkage,
@@ -458,44 +459,39 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
   DtorFunc->setSection(".text.startup");
 
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
  /*isVarArg*/ false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
-  auto *RegFatEndTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *RegFatEndTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+/*isVarArg*/ false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
-  auto *UnregFatTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *UnregFatTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+   /*isVarArg*/ false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
-  auto *AtExitTy =
-  FunctionType::get(Type::getInt32Ty(C), DtorFuncTy->getPointerTo(),
-/*isVarArg*/ false);
+  auto *AtExitTy = FunctionType::get(Type::getInt32Ty(C), PtrTy,
+ /*isVarArg*/ false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(
-  M, PointerType::getUnqual(C)->getPointerTo(), false,
-  llvm::GlobalValue::InternalLinkage,
-  
llvm::ConstantPointerNull::get(PointerType::getUnqual(C)->getPointerTo()),
+  M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+  llvm::ConstantPointerNull::get(PtrTy),
   IsHIP ? ".hip.binary_handle" : ".cuda.binary_handle");
 
   // Create the constructor to register this image with the runtime.
   IRBuilder<> CtorBuilder(BasicBlock::Create(C, "entry", CtorFunc));
   CallInst *Handle = CtorBuilder.CreateCall(
-  RegFatbin, ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- FatbinDesc, PointerType::getUnqual(C)));
+  RegFatbin,
+  ConstantExpr::getPointerBitCastOrAddrSpaceCast(FatbinDesc, PtrTy));
   CtorBuilder.CreateAlignedStore(
   Handle, BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP), Handle);
   if (!IsHIP)
 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
@@ -507,8 +503,8 @@ void createRegisterFatbinFunction(Module , GlobalVariable 
*FatbinDesc,
   // `atexit()` intead.
   IRBuilder<> DtorBuilder(BasicBlock::Create(C, "entry", DtorFunc));
   LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
-  PointerType::getUnqual(C)->getPointerTo(), BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  PtrTy, BinaryHandleGlobal,
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
   DtorBuilder.CreateRetVoid();
 

``




https://github.com/llvm/llvm-project/pull/73374
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[clang] [clang-linker-wrapper] Re-use type returned from 'PointerType::getUnqual(C)' (NFC) (PR #73374)

2023-11-24 Thread Youngsuk Kim via cfe-commits

https://github.com/JOE1994 created 
https://github.com/llvm/llvm-project/pull/73374

Multiple calls to `PointerType::getUnqual(C)`, and calls to 
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function 
`createRegisterGlobalsFunction()`.

>From cd36ba2c52f14051cbe82efc6390a036f75d2b46 Mon Sep 17 00:00:00 2001
From: Youngsuk Kim 
Date: Thu, 23 Nov 2023 10:54:07 -0600
Subject: [PATCH] [clang-linker-wrapper] Re-use type returned from
 'PointerType::getUnqual(C)' (NFC)

Multiple calls to `PointerType::getUnqual(C)`, and calls to
`Type::getPointerTo(AddrSpace=0)` on them all result in the same type.

Clean them up to re-use the same `PtrTy` variable within function
`createRegisterGlobalsFunction()`.
---
 .../clang-linker-wrapper/OffloadWrapper.cpp   | 34 ---
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp 
b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
index 4bbfba777e1854f..5daa7c083b564e0 100644
--- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp
@@ -445,6 +445,7 @@ Function *createRegisterGlobalsFunction(Module , bool 
IsHIP) {
 void createRegisterFatbinFunction(Module , GlobalVariable *FatbinDesc,
   bool IsHIP) {
   LLVMContext  = M.getContext();
+  auto *PtrTy = PointerType::getUnqual(C);
   auto *CtorFuncTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg*/ false);
   auto *CtorFunc =
   Function::Create(CtorFuncTy, GlobalValue::InternalLinkage,
@@ -458,44 +459,39 @@ void createRegisterFatbinFunction(Module , 
GlobalVariable *FatbinDesc,
   DtorFunc->setSection(".text.startup");
 
   // Get the __cudaRegisterFatBinary function declaration.
-  auto *RegFatTy = FunctionType::get(PointerType::getUnqual(C)->getPointerTo(),
- PointerType::getUnqual(C),
+  auto *RegFatTy = FunctionType::get(PtrTy, PtrTy,
  /*isVarArg*/ false);
   FunctionCallee RegFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipRegisterFatBinary" : "__cudaRegisterFatBinary", RegFatTy);
   // Get the __cudaRegisterFatBinaryEnd function declaration.
-  auto *RegFatEndTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *RegFatEndTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+/*isVarArg*/ false);
   FunctionCallee RegFatbinEnd =
   M.getOrInsertFunction("__cudaRegisterFatBinaryEnd", RegFatEndTy);
   // Get the __cudaUnregisterFatBinary function declaration.
-  auto *UnregFatTy = FunctionType::get(
-  Type::getVoidTy(C), PointerType::getUnqual(C)->getPointerTo(),
-  /*isVarArg*/ false);
+  auto *UnregFatTy = FunctionType::get(Type::getVoidTy(C), PtrTy,
+   /*isVarArg*/ false);
   FunctionCallee UnregFatbin = M.getOrInsertFunction(
   IsHIP ? "__hipUnregisterFatBinary" : "__cudaUnregisterFatBinary",
   UnregFatTy);
 
-  auto *AtExitTy =
-  FunctionType::get(Type::getInt32Ty(C), DtorFuncTy->getPointerTo(),
-/*isVarArg*/ false);
+  auto *AtExitTy = FunctionType::get(Type::getInt32Ty(C), PtrTy,
+ /*isVarArg*/ false);
   FunctionCallee AtExit = M.getOrInsertFunction("atexit", AtExitTy);
 
   auto *BinaryHandleGlobal = new llvm::GlobalVariable(
-  M, PointerType::getUnqual(C)->getPointerTo(), false,
-  llvm::GlobalValue::InternalLinkage,
-  
llvm::ConstantPointerNull::get(PointerType::getUnqual(C)->getPointerTo()),
+  M, PtrTy, false, llvm::GlobalValue::InternalLinkage,
+  llvm::ConstantPointerNull::get(PtrTy),
   IsHIP ? ".hip.binary_handle" : ".cuda.binary_handle");
 
   // Create the constructor to register this image with the runtime.
   IRBuilder<> CtorBuilder(BasicBlock::Create(C, "entry", CtorFunc));
   CallInst *Handle = CtorBuilder.CreateCall(
-  RegFatbin, ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- FatbinDesc, PointerType::getUnqual(C)));
+  RegFatbin,
+  ConstantExpr::getPointerBitCastOrAddrSpaceCast(FatbinDesc, PtrTy));
   CtorBuilder.CreateAlignedStore(
   Handle, BinaryHandleGlobal,
-  Align(M.getDataLayout().getPointerTypeSize(PointerType::getUnqual(C;
+  Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
   CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP), Handle);
   if (!IsHIP)
 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
@@ -507,8 +503,8 @@ void createRegisterFatbinFunction(Module , GlobalVariable 
*FatbinDesc,
   // `atexit()` intead.
   IRBuilder<> DtorBuilder(BasicBlock::Create(C, "entry", DtorFunc));
   LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
-  PointerType::getUnqual(C)->getPointerTo(), BinaryHandleGlobal,
-  

[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Shilei Tian via cfe-commits

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


[clang] 85b2e9c - [Clang][OpenMP] Emit unsupported directive error (#70233)

2023-11-24 Thread via cfe-commits

Author: Raymond Chang
Date: 2023-11-24T16:28:32-05:00
New Revision: 85b2e9c02295a54100d41207cddce5908b8c513f

URL: 
https://github.com/llvm/llvm-project/commit/85b2e9c02295a54100d41207cddce5908b8c513f
DIFF: 
https://github.com/llvm/llvm-project/commit/85b2e9c02295a54100d41207cddce5908b8c513f.diff

LOG: [Clang][OpenMP] Emit unsupported directive error (#70233)

Hello!

This PR fixes #63871. Clang should no longer crash and instead emits an
error message.

Below is an example of the new error message:

```
~/dev/fork-llvm-project omp_dispatch_unimpl
❯ ./install/bin/clang -fopenmp  -c -emit-llvm -Xclang -disable-llvm-passes 
test.c
test.c:6:5: error: cannot compile this OpenMP dispatch directive yet
6 | #pragma omp dispatch
  | ^~~~
1 error generated.
```

Added: 
clang/test/OpenMP/dispatch_unsupported.c

Modified: 
clang/lib/CodeGen/CGStmt.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index a7100c8fae2eff9..a5cb80640641bb2 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -407,7 +407,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-llvm_unreachable("Dispatch directive not supported yet.");
+CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
 break;
   case Stmt::OMPScopeDirectiveClass:
 llvm_unreachable("scope not supported with FE outlining");

diff  --git a/clang/test/OpenMP/dispatch_unsupported.c 
b/clang/test/OpenMP/dispatch_unsupported.c
new file mode 100644
index 000..92f555e4b414f4e
--- /dev/null
+++ b/clang/test/OpenMP/dispatch_unsupported.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -fopenmp -disable-llvm-passes %s -verify=expected
+
+// expected-error@+2 {{cannot compile this OpenMP dispatch directive yet}} 
+void a(){
+#pragma omp dispatch
+a();
+}



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


[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Raymond Chang via cfe-commits


@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -fopenmp -disable-llvm-passes %s -verify=expected
+
+// expected-error@+2 {{cannot compile this OpenMP dispatch directive yet}} 
+void a(){
+#pragma omp dispatch
+a();
+}

rkchang wrote:

Added, thanks

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


[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Raymond Chang via cfe-commits

https://github.com/rkchang updated 
https://github.com/llvm/llvm-project/pull/70233

>From 72c056b825963d0de1dcf3fe3a6de922098d0ad9 Mon Sep 17 00:00:00 2001
From: Raymond Chang 
Date: Thu, 12 Oct 2023 01:51:03 -0400
Subject: [PATCH 1/3] Emit unsupported directive error

---
 clang/lib/CodeGen/CGStmt.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c719df1bfa05036..4eeaf9645a3eab8 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -407,7 +407,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-llvm_unreachable("Dispatch directive not supported yet.");
+CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
 break;
   case Stmt::OMPScopeDirectiveClass:
 llvm_unreachable("scope not supported with FE outlining");

>From 65d61090cf6f66a8b6a236e24a775806b5339df9 Mon Sep 17 00:00:00 2001
From: Raymond Chang 
Date: Wed, 22 Nov 2023 01:03:31 -0500
Subject: [PATCH 2/3] Add test case

---
 clang/test/OpenMP/dispatch_unsupported.c | 7 +++
 1 file changed, 7 insertions(+)
 create mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/test/OpenMP/dispatch_unsupported.c 
b/clang/test/OpenMP/dispatch_unsupported.c
new file mode 100644
index 000..ff0815dda6a3fd9
--- /dev/null
+++ b/clang/test/OpenMP/dispatch_unsupported.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -fopenmp -disable-llvm-passes %s -verify=expected
+
+// expected-error@+2 {{cannot compile this OpenMP dispatch directive yet}} 
+void a(){
+#pragma omp dispatch
+a();
+}
\ No newline at end of file

>From 3601f5a5ba41efdb0904a6b790aaa641321110fe Mon Sep 17 00:00:00 2001
From: Raymond Chang 
Date: Fri, 24 Nov 2023 16:23:01 -0500
Subject: [PATCH 3/3] Add empty line

---
 clang/test/OpenMP/dispatch_unsupported.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/OpenMP/dispatch_unsupported.c 
b/clang/test/OpenMP/dispatch_unsupported.c
index ff0815dda6a3fd9..92f555e4b414f4e 100644
--- a/clang/test/OpenMP/dispatch_unsupported.c
+++ b/clang/test/OpenMP/dispatch_unsupported.c
@@ -4,4 +4,4 @@
 void a(){
 #pragma omp dispatch
 a();
-}
\ No newline at end of file
+}

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


[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Shilei Tian via cfe-commits

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


[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Shilei Tian via cfe-commits


@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -fopenmp -disable-llvm-passes %s -verify=expected
+
+// expected-error@+2 {{cannot compile this OpenMP dispatch directive yet}} 
+void a(){
+#pragma omp dispatch
+a();
+}

shiltian wrote:

Leave an empty line at the end of the file

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


[clang] [Clang][OpenMP] Emit unsupported directive error (PR #70233)

2023-11-24 Thread Shilei Tian via cfe-commits

https://github.com/shiltian approved this pull request.

LG with a nit

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


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Daniel Grumberg (daniel-grumberg)


Changes

Ensure that block types get represented correctly in declaration fragments, as 
block parameter names are important for documentation clients we need a 
separate system from getFragmentsForType in order to have access to full 
ParmVarDecls for the parameters.

rdar://118257401

---

Patch is 36.77 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/73369.diff


7 Files Affected:

- (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+6) 
- (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+148-28) 
- (added) clang/test/ExtractAPI/objc_block.m (+965) 
- (modified) clang/test/ExtractAPI/objc_category.m (+4) 
- (modified) clang/test/ExtractAPI/objc_id_protocol.m (+8) 
- (modified) clang/test/ExtractAPI/objc_interface.m (+4) 
- (modified) clang/test/ExtractAPI/objc_property.m (+24) 


``diff
diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 316d83df13e9359..d719196b9a43ecb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -24,6 +24,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/SmallVector.h"
@@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a parameter variable declaration
   /// ParmVarDecl.
   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
+
+  static DeclarationFragments
+  getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc ,
+   FunctionProtoTypeLoc ,
+   DeclarationFragments );
 };
 
 template 
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 02fa6cd6119ecac..eb6eea0aaf54655 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/QualTypeNames.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc ,
+ clang::FunctionProtoTypeLoc ) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;
+  }
+}
+
+} // namespace
+
 DeclarationFragments ::appendSpace() {
   if (!Fragments.empty()) {
 Fragment  = Fragments.back();
@@ -218,7 +254,7 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   // Declaration fragments of a pointer type is the declaration fragments of
   // the pointee type followed by a `*`,
-  if (T->isPointerType())
+  if (T->isPointerType() && !T->isFunctionPointerType())
 return Fragments
 .append(getFragmentsForType(T->getPointeeType(), Context, After))
 .append(" *", DeclarationFragments::FragmentKind::Text);
@@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
 .append(VarDecl::getStorageClassSpecifierString(SC),
 DeclarationFragments::FragmentKind::Keyword)
 .appendSpace();
-  QualType T =
-  Var->getTypeSourceInfo()
-  ? Var->getTypeSourceInfo()->getType()
-  : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
 
   // Capture potential fragments that needs to be placed after the variable 
name
   // ```
@@ -460,8 +492,23 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
   // char (*ptr_to_array)[6];
   // ```
   DeclarationFragments After;
-  return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
-  .appendSpace()
+  FunctionTypeLoc BlockLoc;
+  FunctionProtoTypeLoc BlockProtoLoc;
+  findTypeLocForBlockDecl(Var->getTypeSourceInfo(), BlockLoc, BlockProtoLoc);
+
+  if (!BlockLoc) {
+

[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-24 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg created 
https://github.com/llvm/llvm-project/pull/73369

Ensure that block types get represented correctly in declaration fragments, as 
block parameter names are important for documentation clients we need a 
separate system from getFragmentsForType in order to have access to full 
ParmVarDecls for the parameters.

rdar://118257401

>From e0a9db8aa5e511e81836b5f8e59853c0b498cadf Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 24 Nov 2023 20:34:49 +
Subject: [PATCH] [clang][ExtractAPI] Add support for blocks in declaration
 fragments

Ensure that block types get represented correctly in declaration
fragments, as block parameter names are important for documentation
clients we need a separate system from getFragmentsForType in order to
have access to full ParmVarDecls for the parameters.

rdar://118257401
---
 .../clang/ExtractAPI/DeclarationFragments.h   |   6 +
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 176 +++-
 clang/test/ExtractAPI/objc_block.m| 965 ++
 clang/test/ExtractAPI/objc_category.m |   4 +
 clang/test/ExtractAPI/objc_id_protocol.m  |   8 +
 clang/test/ExtractAPI/objc_interface.m|   4 +
 clang/test/ExtractAPI/objc_property.m |  24 +
 7 files changed, 1159 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/ExtractAPI/objc_block.m

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 316d83df13e9359..d719196b9a43ecb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -24,6 +24,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/SmallVector.h"
@@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a parameter variable declaration
   /// ParmVarDecl.
   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
+
+  static DeclarationFragments
+  getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc ,
+   FunctionProtoTypeLoc ,
+   DeclarationFragments );
 };
 
 template 
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 02fa6cd6119ecac..eb6eea0aaf54655 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/QualTypeNames.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc ,
+ clang::FunctionProtoTypeLoc ) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;
+  }
+}
+
+} // namespace
+
 DeclarationFragments ::appendSpace() {
   if (!Fragments.empty()) {
 Fragment  = Fragments.back();
@@ -218,7 +254,7 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   // Declaration fragments of a pointer type is the declaration fragments of
   // the pointee type followed by a `*`,
-  if (T->isPointerType())
+  if (T->isPointerType() && !T->isFunctionPointerType())
 return Fragments
 .append(getFragmentsForType(T->getPointeeType(), Context, After))
 .append(" *", DeclarationFragments::FragmentKind::Text);
@@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
 .append(VarDecl::getStorageClassSpecifierString(SC),
 DeclarationFragments::FragmentKind::Keyword)
 .appendSpace();
-  QualType T =
-  Var->getTypeSourceInfo()
-  ? Var->getTypeSourceInfo()->getType()
-  : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
 
   // Capture potential fragments that needs to be placed after the variable 
name
   // ```
@@ -460,8 +492,23 @@ 

[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits

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


[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-11-24 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Nathan Sidwell (urnathan)


Changes

I noticed that TBAA BaseTypeMetadataCache can legitimately store null values, 
but it also uses that to mean 'no entry'. Thus nullptr entries get continually 
recalculated. (AFAICT null entries can never become non-null.)  This changes 
the hash lookup/insertion to use find and try_emplace rather than the subscript 
operator.

While there, getBaseTypeInfoHelper will insert non-null values into the 
hashtable itself, but simply return nullptr values.  The only caller, 
getBaseTypeInfo unconditionally inserts the value anyway. It seems clearer to 
let getBaseTypeInfo do the insertion and getBaseTypeInfoHelper merely computes.

[This is the second of a pair of prs]

---
Full diff: https://github.com/llvm/llvm-project/pull/73264.diff


1 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+15-9) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..94dc304bfc243b9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -342,7 +342,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   // field. Virtual bases are more complex and omitted, but avoid an
   // incomplete view for NewStructPathTBAA.
   if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
   for (const CXXBaseSpecifier  : CXXRD->bases()) {
 if (B.isVirtual())
   continue;
@@ -354,7 +354,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
  ? getBaseTypeInfo(BaseQTy)
  : getTypeInfo(BaseQTy);
 if (!TypeNode)
-  return BaseTypeMetadataCache[Ty] = nullptr;
+  return nullptr;
 uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
 uint64_t Size =
 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
@@ -378,7 +378,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
   llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
   getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
   if (!TypeNode)
-return BaseTypeMetadataCache[Ty] = nullptr;
+return nullptr;
 
   uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
   uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
@@ -418,14 +418,20 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
 return nullptr;
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
-return N;
 
-  // Note that the following helper call is allowed to add new nodes to the
-  // cache, which invalidates all its previously obtained iterators. So we
-  // first generate the node for the type and then add that node to the cache.
+  // nullptr is a valid value in the cache, so use find rather than []
+  auto I = BaseTypeMetadataCache.find(Ty);
+  if (I != BaseTypeMetadataCache.end())
+return I->second;
+
+  // First calculate the metadata, before recomputing the insertion point, as
+  // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  return BaseTypeMetadataCache[Ty] = TypeNode;
+  LLVM_ATTRIBUTE_UNUSED auto inserted =
+  BaseTypeMetadataCache.try_emplace(Ty, TypeNode);
+  assert(inserted.second && "BaseType metadata was already inserted");
+
+  return TypeNode;
 }
 
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {

``




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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Nathan Sidwell (urnathan)


Changes

I noticed a couple of minor issues with CodeGenTBAA::getBaseTypeInfo.

1) isValidBaseType explicitly checks for a reference type to return false, but 
then also returns false for all non-record types. Just remove that reference 
check.

2) All uses of CodeGenTBAA::getBaseTypeInfo from within that class are when 
we've already checked the type isValidBaseType. The only case where this isn't 
true is from outside the class. It seems better to have two entry points in 
this case.  Adding a new
'maybeGetBaseTypeInfo' entry point for external uses that returns nullptr for 
non valid base types.  (Open to other names?)

[This is part one of a pair of changes.]

---
Full diff: https://github.com/llvm/llvm-project/pull/73263.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+5-4) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.h (+8-3) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 7cdf50a281cd278..e01fdc3579d88b8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1318,7 +1318,7 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType 
QTy) {
 llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
   if (!TBAA)
 return nullptr;
-  return TBAA->getBaseTypeInfo(QTy);
+  return TBAA->maybeGetBaseTypeInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..9b45a644937b8d9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -95,8 +95,6 @@ static bool TypeHasMayAlias(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy->isReferenceType())
-return false;
   if (const RecordType *TTy = QTy->getAs()) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 // Incomplete types are not valid base access types.
@@ -414,8 +412,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
 }
 
 llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  if (!isValidBaseType(QTy))
-return nullptr;
+  assert(isValidBaseType(QTy) && "Must be a valid base type");
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
   if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
@@ -428,6 +425,10 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
   return BaseTypeMetadataCache[Ty] = TypeNode;
 }
 
+llvm::MDNode *CodeGenTBAA::maybeGetBaseTypeInfo(QualType QTy) {
+  return isValidBaseType(QTy) ? getBaseTypeInfo(QTy) : nullptr;
+}
+
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
   assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
 
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index a65963596fe9def..53d77e1fefc4352 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -166,6 +166,10 @@ class CodeGenTBAA {
   /// used to describe accesses to objects of the given base type.
   llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
 
+  /// getBaseTypeInfo - Return metadata that describes the given base access
+  /// type. The type must be suitable.
+  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+
 public:
   CodeGenTBAA(ASTContext , llvm::Module , const CodeGenOptions ,
   const LangOptions , MangleContext );
@@ -187,9 +191,10 @@ class CodeGenTBAA {
   /// the given type.
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
-  /// getBaseTypeInfo - Get metadata that describes the given base access type.
-  /// Return null if the type is not suitable for use in TBAA access tags.
-  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+  /// maybeGetBaseTypeInfo - Get metadata that describes the given base access
+  /// type. Return null if the type is not suitable for use in TBAA access
+  /// tags.
+  llvm::MDNode *maybeGetBaseTypeInfo(QualType QTy);
 
   /// getAccessTagInfo - Get TBAA tag for a given memory access.
   llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);

``




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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nathan Sidwell (urnathan)


Changes

I noticed a couple of minor issues with CodeGenTBAA::getBaseTypeInfo.

1) isValidBaseType explicitly checks for a reference type to return false, but 
then also returns false for all non-record types. Just remove that reference 
check.

2) All uses of CodeGenTBAA::getBaseTypeInfo from within that class are when 
we've already checked the type isValidBaseType. The only case where this isn't 
true is from outside the class. It seems better to have two entry points in 
this case.  Adding a new
'maybeGetBaseTypeInfo' entry point for external uses that returns nullptr for 
non valid base types.  (Open to other names?)

[This is part one of a pair of changes.]

---
Full diff: https://github.com/llvm/llvm-project/pull/73263.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+5-4) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.h (+8-3) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 7cdf50a281cd278..e01fdc3579d88b8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1318,7 +1318,7 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType 
QTy) {
 llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
   if (!TBAA)
 return nullptr;
-  return TBAA->getBaseTypeInfo(QTy);
+  return TBAA->maybeGetBaseTypeInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 8705d3d65f1a573..9b45a644937b8d9 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -95,8 +95,6 @@ static bool TypeHasMayAlias(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy->isReferenceType())
-return false;
   if (const RecordType *TTy = QTy->getAs()) {
 const RecordDecl *RD = TTy->getDecl()->getDefinition();
 // Incomplete types are not valid base access types.
@@ -414,8 +412,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type 
*Ty) {
 }
 
 llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  if (!isValidBaseType(QTy))
-return nullptr;
+  assert(isValidBaseType(QTy) && "Must be a valid base type");
 
   const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
   if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
@@ -428,6 +425,10 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
   return BaseTypeMetadataCache[Ty] = TypeNode;
 }
 
+llvm::MDNode *CodeGenTBAA::maybeGetBaseTypeInfo(QualType QTy) {
+  return isValidBaseType(QTy) ? getBaseTypeInfo(QTy) : nullptr;
+}
+
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
   assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
 
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index a65963596fe9def..53d77e1fefc4352 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -166,6 +166,10 @@ class CodeGenTBAA {
   /// used to describe accesses to objects of the given base type.
   llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
 
+  /// getBaseTypeInfo - Return metadata that describes the given base access
+  /// type. The type must be suitable.
+  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+
 public:
   CodeGenTBAA(ASTContext , llvm::Module , const CodeGenOptions ,
   const LangOptions , MangleContext );
@@ -187,9 +191,10 @@ class CodeGenTBAA {
   /// the given type.
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
-  /// getBaseTypeInfo - Get metadata that describes the given base access type.
-  /// Return null if the type is not suitable for use in TBAA access tags.
-  llvm::MDNode *getBaseTypeInfo(QualType QTy);
+  /// maybeGetBaseTypeInfo - Get metadata that describes the given base access
+  /// type. Return null if the type is not suitable for use in TBAA access
+  /// tags.
+  llvm::MDNode *maybeGetBaseTypeInfo(QualType QTy);
 
   /// getAccessTagInfo - Get TBAA tag for a given memory access.
   llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);

``




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


[clang] [clang] Avoid recalculating TBAA base type info (PR #73264)

2023-11-24 Thread Nathan Sidwell via cfe-commits

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


[clang] [clang][NFC] Adjust TBAA Base Info API (PR #73263)

2023-11-24 Thread Nathan Sidwell via cfe-commits

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


[libcxx] [libunwind] [llvm] [libc++] Allow running the test suite with optimizations (PR #68753)

2023-11-24 Thread Mark de Wever via cfe-commits

https://github.com/mordante approved this pull request.

LGTM!

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


[clang] [AMDGPU] Treat printf as builtin for OpenCL (PR #72554)

2023-11-24 Thread Vikram Hegde via cfe-commits

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


[clang] [AMDGPU] Treat printf as builtin for OpenCL (PR #72554)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -406,5 +410,9 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", 
"nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts")
 
+// OpenCL
+LANGBUILTIN(printf, "icC*4.", "fp:0:", ALL_OCL_LANGUAGES)

vikramRH wrote:

@ssahasra , I still feel this is the way to move here since I dont see a way to 
access the printf option at IR level and thus decide version of printf to use. 
It has to be at clang CodeGen. I ask other reviewers too if they feel there are 
major concerns with adding such a builtin variant (i.e AMDGPU and OCL 
specific). I might have to look for alternative approaches if so. 

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -26,28 +26,31 @@ using namespace llvm;
 
 #define DEBUG_TYPE "amdgpu-emit-printf"
 
-static Value *fitArgInto64Bits(IRBuilder<> , Value *Arg) {
+static Value *fitArgInto64Bits(IRBuilder<> , Value *Arg,
+   bool IsBuffered) {
+  const DataLayout  = 
Builder.GetInsertBlock()->getModule()->getDataLayout();
   auto Int64Ty = Builder.getInt64Ty();
   auto Ty = Arg->getType();
 
   if (auto IntTy = dyn_cast(Ty)) {
-switch (IntTy->getBitWidth()) {
-case 32:
-  return Builder.CreateZExt(Arg, Int64Ty);
-case 64:
-  return Arg;
+if (IntTy->getBitWidth() < 64) {
+  return Builder.CreateZExt(Arg, Builder.getInt64Ty());
 }
   }
 
-  if (Ty->getTypeID() == Type::DoubleTyID) {
+  if (Ty->isFloatingPointTy()) {
+if (DL.getTypeAllocSize(Ty) < 8)
+  Arg = Builder.CreateFPExt(Arg, Builder.getDoubleTy());

vikramRH wrote:

The type cast is necessary  for types such as _Float16, which is not handled at 
argument promotion. I have added a test case to show the same

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -26,28 +26,31 @@ using namespace llvm;
 
 #define DEBUG_TYPE "amdgpu-emit-printf"
 
-static Value *fitArgInto64Bits(IRBuilder<> , Value *Arg) {
+static Value *fitArgInto64Bits(IRBuilder<> , Value *Arg,
+   bool IsBuffered) {
+  const DataLayout  = 
Builder.GetInsertBlock()->getModule()->getDataLayout();
   auto Int64Ty = Builder.getInt64Ty();
   auto Ty = Arg->getType();
 
   if (auto IntTy = dyn_cast(Ty)) {
-switch (IntTy->getBitWidth()) {
-case 32:
-  return Builder.CreateZExt(Arg, Int64Ty);
-case 64:
-  return Arg;
+if (IntTy->getBitWidth() < 64) {
+  return Builder.CreateZExt(Arg, Builder.getInt64Ty());
 }
   }
 
-  if (Ty->getTypeID() == Type::DoubleTyID) {
+  if (Ty->isFloatingPointTy()) {
+if (DL.getTypeAllocSize(Ty) < 8)
+  Arg = Builder.CreateFPExt(Arg, Builder.getDoubleTy());
+if (IsBuffered)
+  return Arg;
 return Builder.CreateBitCast(Arg, Int64Ty);
   }
 
-  if (isa(Ty)) {
+  if (!IsBuffered && isa(Ty)) {
 return Builder.CreatePtrToInt(Arg, Int64Ty);

vikramRH wrote:

The pointer is just pushed onto the buffer. The cast is necessary for the 
hostcall case to be compatible with device lib functions

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -170,20 +173,49 @@ static Value *appendString(IRBuilder<> , Value 
*Desc, Value *Arg,
   return callAppendStringN(Builder, Desc, Arg, Length, IsLast);
 }
 
+static Value *appendVectorArg(IRBuilder<> , Value *Desc, Value *Arg,
+  bool IsLast, bool IsBuffered) {
+  assert(Arg->getType()->isVectorTy() && "incorrent append* function");
+  auto VectorTy = dyn_cast(Arg->getType());
+  auto Zero = Builder.getInt64(0);
+  if (VectorTy) {

vikramRH wrote:

I have changed this code a little now so that only FixedVectorTypes are 
handled. This should be okay since the OCL specs specifically say only vectors 
of length 2,3,4,8 and 16 are supported for printf.

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -194,6 +226,8 @@ static void locateCStrings(SparseBitVector<8> , 
StringRef Str) {
   SpecPos += 2;
   continue;
 }
+if (Str.find_first_of("v", SpecPos) != StringRef::npos)

vikramRH wrote:

Fixed

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -170,20 +173,49 @@ static Value *appendString(IRBuilder<> , Value 
*Desc, Value *Arg,
   return callAppendStringN(Builder, Desc, Arg, Length, IsLast);
 }
 
+static Value *appendVectorArg(IRBuilder<> , Value *Desc, Value *Arg,
+  bool IsLast, bool IsBuffered) {
+  assert(Arg->getType()->isVectorTy() && "incorrent append* function");
+  auto VectorTy = dyn_cast(Arg->getType());
+  auto Zero = Builder.getInt64(0);
+  if (VectorTy) {
+for (unsigned int i = 0; i < VectorTy->getNumElements() - 1; i++) {
+  auto Val = Builder.CreateExtractElement(Arg, i);
+  Desc = callAppendArgs(Builder, Desc, 1,
+fitArgInto64Bits(Builder, Val, IsBuffered), Zero,
+Zero, Zero, Zero, Zero, Zero, false);
+}
+
+Value* Val =
+Builder.CreateExtractElement(Arg, VectorTy->getNumElements() - 1);
+return callAppendArgs(Builder, Desc, 1,
+  fitArgInto64Bits(Builder, Val, IsBuffered), Zero,
+  Zero, Zero, Zero, Zero, Zero, IsLast);
+  }
+  return nullptr;
+}
+
 static Value *processArg(IRBuilder<> , Value *Desc, Value *Arg,
- bool SpecIsCString, bool IsLast) {
+ bool SpecIsCString, bool IsVector, bool IsLast,
+ bool IsBuffered) {
   if (SpecIsCString && isa(Arg->getType())) {
 return appendString(Builder, Desc, Arg, IsLast);
   }
-  // If the format specifies a string but the argument is not, the frontend 
will
-  // have printed a warning. We just rely on undefined behaviour and send the
-  // argument anyway.
-  return appendArg(Builder, Desc, Arg, IsLast);
+
+  if (IsVector) {
+return appendVectorArg(Builder, Desc, Arg, IsLast, IsBuffered);
+  } 
+
+  // If the format specifies a string but the argument is not, the frontend
+  // will have printed a warning. We just rely on undefined behaviour and send
+  // the argument anyway.
+  return appendArg(Builder, Desc, Arg, IsLast, IsBuffered);
 }
 
 // Scan the format string to locate all specifiers, and mark the ones that
 // specify a string, i.e, the "%s" specifier with optional '*' characters.
-static void locateCStrings(SparseBitVector<8> , StringRef Str) {
+static void locateCStringsAndVectors(SparseBitVector<8> ,

vikramRH wrote:

Done

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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits


@@ -1,12 +1,68 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
-// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-mprintf-kind=buffered -disable-llvm-passes -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK_BUFFERED %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -triple amdgcn-amd-amdhsa 
-mprintf-kind=hostcall -disable-llvm-passes -emit-llvm -o - %s | FileCheck 
--check-prefix=CHECK_HOSTCALL %s
 
 int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 
2)));

vikramRH wrote:

Done

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Piotr Zegar via cfe-commits


@@ -319,6 +319,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(hasExplicitSpecifier);
   REGISTER_MATCHER(hasExternalFormalLinkage);
   REGISTER_MATCHER(hasFalseExpression);
+  REGISTER_MATCHER(hasFoldInit);

PiotrZSL wrote:

I think that you should also register here other matchers like isBinaryFold to 
make them visible in clang-query.

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Piotr Zegar via cfe-commits

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL commented:

Overall looks fine, but I didn't check test too deeply.
Someone said not so long ago that we do not want to add matchers unless there 
is some usecase for them in some of the tools. Pull request doesn't say 
anything.
Whats a purpose of those matchers (except only to have them).


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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Piotr Zegar via cfe-commits


@@ -4532,6 +4563,139 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
   return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
 }
 
+/// Matches the operand that does not contain the parameter pack.
+///
+/// Example matches `(0 + ... + args)` and `(args * ... * 1)`
+/// (matcher = cxxFoldExpr(hasFoldInit(expr(
+///   with hasFoldInit(...)
+/// matching `0` and `1` respectively
+/// \code
+///   template 
+///   auto sum(Args... args) {
+///   return (0 + ... + args);
+///   }
+///
+///   template 
+///   auto multiply(Args... args) {
+///   return (args * ... * 1);
+///   }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher,
+  InnerMacher) {
+  const auto *const Init = Node.getInit();
+  return Init && InnerMacher.matches(*Init, Finder, Builder);
+}
+
+/// Matches the operand that contains the parameter pack.
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(hasPattern(expr(
+///   with hasPattern(...)
+/// matching `args`
+/// \code
+///   template 
+///   auto sum(Args... args) {
+///   return (0 + ... + args);
+///   }
+///
+///   template 
+///   auto multiply(Args... args) {
+///   return (args * ... * 1);
+///   }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher,
+  InnerMacher) {
+  return InnerMacher.matches(*Node.getPattern(), Finder, Builder);

PiotrZSL wrote:

maybe check if getPattern will return not null

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


[clang] [clang][ASTImporter] Improve structural equivalence of overloadable operators. (PR #72242)

2023-11-24 Thread via cfe-commits


@@ -437,12 +439,67 @@ class StmtComparer {
 };
 } // namespace
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ const UnaryOperator *E1,
+ const CXXOperatorCallExpr *E2) {
+  return UnaryOperator::getOverloadedOperator(E1->getOpcode()) ==
+ E2->getOperator() &&
+ IsStructurallyEquivalent(Context, E1->getSubExpr(), E2->getArg(0));
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ const CXXOperatorCallExpr *E1,
+ const UnaryOperator *E2) {
+  return E1->getOperator() ==
+ UnaryOperator::getOverloadedOperator(E2->getOpcode()) &&
+ IsStructurallyEquivalent(Context, E1->getArg(0), E2->getSubExpr());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ const BinaryOperator *E1,
+ const CXXOperatorCallExpr *E2) {
+  return BinaryOperator::getOverloadedOperator(E1->getOpcode()) ==
+ E2->getOperator() &&
+ IsStructurallyEquivalent(Context, E1->getLHS(), E2->getArg(0)) &&
+ IsStructurallyEquivalent(Context, E1->getRHS(), E2->getArg(1));
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ const CXXOperatorCallExpr *E1,
+ const BinaryOperator *E2) {
+  return E1->getOperator() ==
+ BinaryOperator::getOverloadedOperator(E2->getOpcode()) &&
+ IsStructurallyEquivalent(Context, E1->getArg(0), E2->getLHS()) &&
+ IsStructurallyEquivalent(Context, E1->getArg(1), E2->getRHS());
+}
+
 /// Determine structural equivalence of two statements.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  const Stmt *S1, const Stmt *S2) {
   if (!S1 || !S2)
 return S1 == S2;
 
+  // Check for statements with similar syntax but different AST.
+  // The unary and binary operators (like '+', '&') can be parsed as
+  // CXXOperatorCall too (and UnaryOperator or BinaryOperator).
+  // This depends on arguments with unresolved type and on the name lookup.

DonatNagyE wrote:

Thanks for the link, it's really helpful. Perhaps it should be included in the 
source code comment as well, to help those who'll work on this code in the 
future.

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


[clang] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2 (PR #72107)

2023-11-24 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


DonatNagyE wrote:

I updated the PR to allow `[size]` for creating the after-the-end pointer 
of an array. My implementation interprets this corner case narrowly to limit 
the amount of false negatives: for example `if (idx >= size) return 
[idx];` is reported as an overflow instead of very optimistically 
assuming that `idx` must be equal to `size`. 

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


[clang] [clang] Use the materialized temporary's type while creating the APValue (PR #73355)

2023-11-24 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff d896b1f5a614daef1c3aa65cb3521ec82bc728d5 
3ff1b189cf55d3705b2823dc39eaaf710fa26541 -- clang/test/SemaCXX/pr72025.cpp 
clang/lib/AST/ExprConstant.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6c6ad12119..0650c91a8f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3185,8 +3185,8 @@ static bool HandleLValueIndirectMember(EvalInfo , 
const Expr *E,
 }
 
 /// Get the size of the given type in char units.
-static bool HandleSizeof(EvalInfo , SourceLocation Loc,
- QualType Type, CharUnits ) {
+static bool HandleSizeof(EvalInfo , SourceLocation Loc, QualType Type,
+ CharUnits ) {
   // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
   // extension.
   if (Type->isVoidType() || Type->isFunctionType()) {
@@ -11516,8 +11516,8 @@ enum class GCCTypeClass {
 
 /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
 /// as GCC.
-static GCCTypeClass
-EvaluateBuiltinClassifyType(QualType T, const LangOptions ) {
+static GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
+const LangOptions ) {
   assert(!T->isDependentType() && "unexpected dependent type");
 
   QualType CanTy = T.getCanonicalType();

``




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


[clang] [llvm] Enable OpenCL hostcall printf (WIP) (PR #72556)

2023-11-24 Thread Vikram Hegde via cfe-commits

https://github.com/vikramRH updated 
https://github.com/llvm/llvm-project/pull/72556

>From 6ace9d0a51064be189093ca3bb42416aafadb7f6 Mon Sep 17 00:00:00 2001
From: Vikram 
Date: Fri, 10 Nov 2023 09:39:41 +
Subject: [PATCH 1/4] [AMDGPU] Treat printf as builtin for OpenCL

---
 clang/include/clang/Basic/BuiltinsAMDGPU.def | 8 
 clang/lib/AST/Decl.cpp   | 7 +++
 clang/lib/Basic/Targets/AMDGPU.cpp   | 2 ++
 clang/lib/CodeGen/CGBuiltin.cpp  | 5 +
 4 files changed, 22 insertions(+)

diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def 
b/clang/include/clang/Basic/BuiltinsAMDGPU.def
index a19c8bd5f219ec6..1799c72806bfdd4 100644
--- a/clang/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def
@@ -21,6 +21,10 @@
 #if defined(BUILTIN) && !defined(TARGET_BUILTIN)
 #   define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
 #endif
+
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+#define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
 
//===--===//
 // SI+ only builtins.
 
//===--===//
@@ -406,5 +410,9 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", 
"nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts")
 
+// OpenCL
+LANGBUILTIN(printf, "icC*4.", "fp:0:", ALL_OCL_LANGUAGES)
+
 #undef BUILTIN
 #undef TARGET_BUILTIN
+#undef LANGBUILTIN
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c5c2edf1bfe3aba..2597422bdd521a0 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -49,6 +49,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetCXXABI.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Visibility.h"
@@ -3598,6 +3599,12 @@ unsigned FunctionDecl::getBuiltinID(bool 
ConsiderWrapperFunctions) const {
   if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static)
 return 0;
 
+  // AMDGCN implementation supports printf as a builtin
+  // for OpenCL
+  if (Context.getTargetInfo().getTriple().isAMDGCN() &&
+  Context.getLangOpts().OpenCL && BuiltinID == AMDGPU::BIprintf)
+return BuiltinID;
+
   // OpenCL v1.2 s6.9.f - The library functions defined in
   // the C99 standard headers are not available.
   if (Context.getLangOpts().OpenCL &&
diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp 
b/clang/lib/Basic/Targets/AMDGPU.cpp
index 409ae32ab424215..307cfa49f54e926 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -91,6 +91,8 @@ static constexpr Builtin::Info BuiltinInfo[] = {
   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)   
\
   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) 
\
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
 #include "clang/Basic/BuiltinsAMDGPU.def"
 };
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 09309a3937fb613..987909b5a62e11b 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2458,6 +2458,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   ().getLongDoubleFormat() == ::APFloat::IEEEquad())
 BuiltinID = mutateLongDoubleBuiltin(BuiltinID);
 
+   // Mutate the printf builtin ID so that we use the same CodeGen path for
+   // HIP and OpenCL with AMDGPU targets.
+   if (getTarget().getTriple().isAMDGCN() && BuiltinID == AMDGPU::BIprintf)
+ BuiltinID = Builtin::BIprintf;
+
   // If the builtin has been declared explicitly with an assembler label,
   // disable the specialized emitting below. Ideally we should communicate the
   // rename in IR, or at least avoid generating the intrinsic calls that are

>From 040a28deef5fe7a5d9e357a898b50335992e708d Mon Sep 17 00:00:00 2001
From: Vikram 
Date: Mon, 20 Nov 2023 05:26:27 +
Subject: [PATCH 2/4] [AMDGPU] Enable OpenCL printf expansion at clang CodeGen

---
 clang/lib/CodeGen/CGBuiltin.cpp   |  3 ++-
 clang/lib/CodeGen/CGGPUBuiltin.cpp| 25 +++--
 clang/lib/Driver/ToolChains/Clang.cpp | 10 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 987909b5a62e11b..8d51df24c7872b7 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5622,7 +5622,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,

[clang] [clang] Use the materialized temporary's type while creating the APValue (PR #73355)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)


Changes

See https://github.com/llvm/llvm-project/issues/72025 for the bug and its 
diagnosis.

---
Full diff: https://github.com/llvm/llvm-project/pull/73355.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/lib/AST/ExprConstant.cpp (+1-1) 
- (added) clang/test/SemaCXX/pr72025.cpp (+9) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 74358219ba9fb22..d434d016907f815 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -691,6 +691,9 @@ Bug Fixes to C++ Support
   Fixes:
   (`#68769 `_)
 
+- Fixed a crash for C++98/03 while checking an ill-formed ``_Static_assert`` 
expression.
+  Fixes: (`#72025 `_)
+
 - Clang now defers the instantiation of explicit specifier until constraint 
checking
   completes (except deduction guides). Fixes:
   (`#59827 `_)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e16fec6109e744e..6c6ad12119d13c3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8607,7 +8607,7 @@ bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
 Result.set(E);
   } else {
 Value = >createTemporary(
-E, E->getType(),
+E, Inner->getType(),
 E->getStorageDuration() == SD_FullExpression ? 
ScopeKind::FullExpression
  : ScopeKind::Block,
 Result);
diff --git a/clang/test/SemaCXX/pr72025.cpp b/clang/test/SemaCXX/pr72025.cpp
new file mode 100644
index 000..9f0a4b0f43630c5
--- /dev/null
+++ b/clang/test/SemaCXX/pr72025.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify -std=c++03 -fsyntax-only %s
+struct V {
+  char c[2];
+  banana V() : c("i") {} // expected-error {{unknown type name}}
+ // expected-error@-1 {{constructor cannot have a 
return type}}
+};
+
+_Static_assert(V().c[0], ""); // expected-error {{is not an integral constant 
expression}}
+

``




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


[clang] [clang] Use the materialized temporary's type while creating the APValue (PR #73355)

2023-11-24 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/73355

See https://github.com/llvm/llvm-project/issues/72025 for the bug and its 
diagnosis.

>From 3ff1b189cf55d3705b2823dc39eaaf710fa26541 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Sat, 25 Nov 2023 02:01:22 +0800
Subject: [PATCH] [clang] Use the materialized temporary's type while creating
 the APValue

See https://github.com/llvm/llvm-project/issues/72025 for the bug and
its diagnosis.
---
 clang/docs/ReleaseNotes.rst| 3 +++
 clang/lib/AST/ExprConstant.cpp | 2 +-
 clang/test/SemaCXX/pr72025.cpp | 9 +
 3 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/pr72025.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 74358219ba9fb22..d434d016907f815 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -691,6 +691,9 @@ Bug Fixes to C++ Support
   Fixes:
   (`#68769 `_)
 
+- Fixed a crash for C++98/03 while checking an ill-formed ``_Static_assert`` 
expression.
+  Fixes: (`#72025 `_)
+
 - Clang now defers the instantiation of explicit specifier until constraint 
checking
   completes (except deduction guides). Fixes:
   (`#59827 `_)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e16fec6109e744e..6c6ad12119d13c3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8607,7 +8607,7 @@ bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
 Result.set(E);
   } else {
 Value = >createTemporary(
-E, E->getType(),
+E, Inner->getType(),
 E->getStorageDuration() == SD_FullExpression ? 
ScopeKind::FullExpression
  : ScopeKind::Block,
 Result);
diff --git a/clang/test/SemaCXX/pr72025.cpp b/clang/test/SemaCXX/pr72025.cpp
new file mode 100644
index 000..9f0a4b0f43630c5
--- /dev/null
+++ b/clang/test/SemaCXX/pr72025.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify -std=c++03 -fsyntax-only %s
+struct V {
+  char c[2];
+  banana V() : c("i") {} // expected-error {{unknown type name}}
+ // expected-error@-1 {{constructor cannot have a 
return type}}
+};
+
+_Static_assert(V().c[0], ""); // expected-error {{is not an integral constant 
expression}}
+

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


[clang-tools-extra] [llvm] [RISCV][Zba] Optimize mul with SH*ADD (PR #68144)

2023-11-24 Thread Alexandr Lekomtsev via cfe-commits


@@ -983,6 +983,1299 @@ define i64 @mul81(i64 %a) {
   ret i64 %c
 }
 
+
+define i64 @mul153(i64 %a) {
+; RV64I-LABEL: mul153:

vacma wrote:

Thanks for your feedback,
tests show that 3 shXadds is _a little_ slower than mul, but for some reason 
GCC uses 3 shXadds - https://godbolt.org/z/oez5Pddde
And even 4 - https://godbolt.org/z/czK3Kd7bs
I'll try to find out why they do this and write later.

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


[clang] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2 (PR #72107)

2023-11-24 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


https://github.com/DonatNagyE updated 
https://github.com/llvm/llvm-project/pull/72107

>From ab102e949994a4462382e4c10c0153d61fb00306 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Mon, 13 Nov 2023 11:16:26 +0100
Subject: [PATCH 1/5] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2

...instead of the currently used, more abstract Location callback. The
main advantage of this change is that after it the checker will check
`array[index].field` while the previous implementation ignored this
situation (because here the ElementRegion is wrapped in a FieldRegion
object). This improvement fixes PR #70187.

Note that after this change `[idx]` will be handled as an access
to the `idx`th element of `array`, which is technically incorrect but
matches the programmer intuitions. In my opinion it's more helpful if
the report points to the source location where the indexing happens
(instead of the location where a pointer is finally dereferenced).

This change introduces false positives in the exceptional corner case
when the past-the-end pointer of an array is formed as `[length]`. I
think this is just unimportant pedantery (because it's cleaner to write
the past-the-end pointer as `(arr+length)` and that form isn't affected
by this checker), but if it does appear in real code, then we could
introduce a special case for it.

In addition to this primary improvement, this change tweaks the message
for the tainted index/offset case (using the more concrete information
that's available now) and clarifies/improves a few testcases.

The main change of this commit (replacing `check::Location` with
`check::PostStmt<...>` callbacks) was already proposed in my change
https://reviews.llvm.org/D150446 and https://reviews.llvm.org/D159107 by
@steakhal. Those reviews were both abandoned, but the issues were
unrelated to the change that is introduced in this PR.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 96 ---
 .../test/Analysis/out-of-bounds-diagnostics.c | 74 --
 .../test/Analysis/taint-diagnostic-visitor.c  |  4 +-
 3 files changed, 129 insertions(+), 45 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index ffc7236d1e2551a..ef3ae42d57c6e88 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -34,20 +34,37 @@ using llvm::formatv;
 namespace {
 enum OOB_Kind { OOB_Precedes, OOB_Exceeds, OOB_Taint };
 
-class ArrayBoundCheckerV2 :
-public Checker {
+struct Messages {
+  std::string Short, Full;
+};
+
+class ArrayBoundCheckerV2 : public Checker,
+   check::PostStmt,
+   check::PostStmt> {
   BugType BT{this, "Out-of-bound access"};
   BugType TaintBT{this, "Out-of-bound access", categories::TaintedData};
 
+  void performCheck(const Expr *E, CheckerContext ) const;
+
   void reportOOB(CheckerContext , ProgramStateRef ErrorState, OOB_Kind Kind,
- NonLoc Offset, std::string RegName, std::string Msg) const;
+ NonLoc Offset, Messages Msgs) const;
 
   static bool isFromCtypeMacro(const Stmt *S, ASTContext );
 
 public:
-  void checkLocation(SVal l, bool isLoad, const Stmt *S,
- CheckerContext ) const;
+  void checkPostStmt(const ArraySubscriptExpr *E, CheckerContext ) const {
+performCheck(E, C);
+  }
+  void checkPostStmt(const UnaryOperator *E, CheckerContext ) const {
+if (E->getOpcode() == UO_Deref)
+  performCheck(E, C);
+  }
+  void checkPostStmt(const MemberExpr *E, CheckerContext ) const {
+if (E->isArrow())
+  performCheck(E->getBase(), C);
+  }
 };
+
 } // anonymous namespace
 
 /// For a given Location that can be represented as a symbolic expression
@@ -217,16 +234,19 @@ static std::string getShortMsg(OOB_Kind Kind, std::string 
RegName) {
   return formatv(ShortMsgTemplates[Kind], RegName);
 }
 
-static std::string getPrecedesMsg(std::string RegName, NonLoc Offset) {
+static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) {
+  std::string RegName = getRegionName(Region);
   SmallString<128> Buf;
   llvm::raw_svector_ostream Out(Buf);
   Out << "Access of " << RegName << " at negative byte offset";
   if (auto ConcreteIdx = Offset.getAs())
 Out << ' ' << ConcreteIdx->getValue();
-  return std::string(Buf);
+  return {getShortMsg(OOB_Precedes, RegName), std::string(Buf)};
 }
-static std::string getExceedsMsg(ASTContext , std::string RegName,
- NonLoc Offset, NonLoc Extent, SVal Location) {
+
+static Messages getExceedsMsgs(ASTContext , const SubRegion *Region,
+   NonLoc Offset, NonLoc Extent, SVal Location) {
+  std::string 

[clang] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2 (PR #72107)

2023-11-24 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


https://github.com/DonatNagyE updated 
https://github.com/llvm/llvm-project/pull/72107

>From ab102e949994a4462382e4c10c0153d61fb00306 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Mon, 13 Nov 2023 11:16:26 +0100
Subject: [PATCH 1/4] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2

...instead of the currently used, more abstract Location callback. The
main advantage of this change is that after it the checker will check
`array[index].field` while the previous implementation ignored this
situation (because here the ElementRegion is wrapped in a FieldRegion
object). This improvement fixes PR #70187.

Note that after this change `[idx]` will be handled as an access
to the `idx`th element of `array`, which is technically incorrect but
matches the programmer intuitions. In my opinion it's more helpful if
the report points to the source location where the indexing happens
(instead of the location where a pointer is finally dereferenced).

This change introduces false positives in the exceptional corner case
when the past-the-end pointer of an array is formed as `[length]`. I
think this is just unimportant pedantery (because it's cleaner to write
the past-the-end pointer as `(arr+length)` and that form isn't affected
by this checker), but if it does appear in real code, then we could
introduce a special case for it.

In addition to this primary improvement, this change tweaks the message
for the tainted index/offset case (using the more concrete information
that's available now) and clarifies/improves a few testcases.

The main change of this commit (replacing `check::Location` with
`check::PostStmt<...>` callbacks) was already proposed in my change
https://reviews.llvm.org/D150446 and https://reviews.llvm.org/D159107 by
@steakhal. Those reviews were both abandoned, but the issues were
unrelated to the change that is introduced in this PR.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 96 ---
 .../test/Analysis/out-of-bounds-diagnostics.c | 74 --
 .../test/Analysis/taint-diagnostic-visitor.c  |  4 +-
 3 files changed, 129 insertions(+), 45 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index ffc7236d1e2551a..ef3ae42d57c6e88 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -34,20 +34,37 @@ using llvm::formatv;
 namespace {
 enum OOB_Kind { OOB_Precedes, OOB_Exceeds, OOB_Taint };
 
-class ArrayBoundCheckerV2 :
-public Checker {
+struct Messages {
+  std::string Short, Full;
+};
+
+class ArrayBoundCheckerV2 : public Checker,
+   check::PostStmt,
+   check::PostStmt> {
   BugType BT{this, "Out-of-bound access"};
   BugType TaintBT{this, "Out-of-bound access", categories::TaintedData};
 
+  void performCheck(const Expr *E, CheckerContext ) const;
+
   void reportOOB(CheckerContext , ProgramStateRef ErrorState, OOB_Kind Kind,
- NonLoc Offset, std::string RegName, std::string Msg) const;
+ NonLoc Offset, Messages Msgs) const;
 
   static bool isFromCtypeMacro(const Stmt *S, ASTContext );
 
 public:
-  void checkLocation(SVal l, bool isLoad, const Stmt *S,
- CheckerContext ) const;
+  void checkPostStmt(const ArraySubscriptExpr *E, CheckerContext ) const {
+performCheck(E, C);
+  }
+  void checkPostStmt(const UnaryOperator *E, CheckerContext ) const {
+if (E->getOpcode() == UO_Deref)
+  performCheck(E, C);
+  }
+  void checkPostStmt(const MemberExpr *E, CheckerContext ) const {
+if (E->isArrow())
+  performCheck(E->getBase(), C);
+  }
 };
+
 } // anonymous namespace
 
 /// For a given Location that can be represented as a symbolic expression
@@ -217,16 +234,19 @@ static std::string getShortMsg(OOB_Kind Kind, std::string 
RegName) {
   return formatv(ShortMsgTemplates[Kind], RegName);
 }
 
-static std::string getPrecedesMsg(std::string RegName, NonLoc Offset) {
+static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) {
+  std::string RegName = getRegionName(Region);
   SmallString<128> Buf;
   llvm::raw_svector_ostream Out(Buf);
   Out << "Access of " << RegName << " at negative byte offset";
   if (auto ConcreteIdx = Offset.getAs())
 Out << ' ' << ConcreteIdx->getValue();
-  return std::string(Buf);
+  return {getShortMsg(OOB_Precedes, RegName), std::string(Buf)};
 }
-static std::string getExceedsMsg(ASTContext , std::string RegName,
- NonLoc Offset, NonLoc Extent, SVal Location) {
+
+static Messages getExceedsMsgs(ASTContext , const SubRegion *Region,
+   NonLoc Offset, NonLoc Extent, SVal Location) {
+  std::string RegName = 

[clang] [Clang][SME2] Add outer product and accumulate/subtract builtins (PR #71176)

2023-11-24 Thread Kerry McLaughlin via cfe-commits


@@ -0,0 +1,170 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | 
opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x 
c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s 
-check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve -S -disable-O0-optnone -Werror -Wall 
-emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve -S -disable-O0-optnone -Werror -Wall 
-emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | 
FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+#include 
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// MOPA
+
+// CHECK-LABEL: @test_svmopa_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CHECK-NEXT:tail call void @llvm.aarch64.sme.smopa.za32.nxv8i16(i32 3, 
 [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CHECK-NEXT:ret void
+//
+// CPP-CHECK-LABEL: @_Z15test_svmopa_s16u10__SVBool_tS_u11__SVInt16_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CPP-CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CPP-CHECK-NEXT:tail call void @llvm.aarch64.sme.smopa.za32.nxv8i16(i32 
3,  [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CPP-CHECK-NEXT:ret void
+//
+void test_svmopa_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) 
__arm_streaming __arm_shared_za {
+  SVE_ACLE_FUNC(svmopa_za32,_s16,_m,)(3, pn, pm, zn, zm);
+}
+
+// CHECK-LABEL: @test_svmopa_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CHECK-NEXT:tail call void @llvm.aarch64.sme.umopa.za32.nxv8i16(i32 3, 
 [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CHECK-NEXT:ret void
+//
+// CPP-CHECK-LABEL: @_Z15test_svmopa_u16u10__SVBool_tS_u12__SVUint16_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CPP-CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CPP-CHECK-NEXT:tail call void @llvm.aarch64.sme.umopa.za32.nxv8i16(i32 
3,  [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CPP-CHECK-NEXT:ret void
+//
+void test_svmopa_u16(svbool_t pn, svbool_t pm, svuint16_t zn, svuint16_t zm) 
__arm_streaming __arm_shared_za {
+  SVE_ACLE_FUNC(svmopa_za32,_u16,_m,)(3, pn, pm, zn, zm);
+}
+
+// MOPS
+
+// CHECK-LABEL: @test_svmops_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CHECK-NEXT:tail call void @llvm.aarch64.sme.smops.za32.nxv8i16(i32 3, 
 [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CHECK-NEXT:ret void
+//
+// CPP-CHECK-LABEL: @_Z15test_svmops_s16u10__SVBool_tS_u11__SVInt16_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CPP-CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CPP-CHECK-NEXT:tail call void @llvm.aarch64.sme.smops.za32.nxv8i16(i32 
3,  [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CPP-CHECK-NEXT:ret void
+//
+void test_svmops_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) 
__arm_streaming __arm_shared_za {
+  SVE_ACLE_FUNC(svmops_za32,_s16,_m,)(3, pn, pm, zn, zm);
+}
+
+// CHECK-LABEL: @test_svmops_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CHECK-NEXT:[[TMP1:%.*]] 

[clang] [Clang][SME2] Add outer product and accumulate/subtract builtins (PR #71176)

2023-11-24 Thread Kerry McLaughlin via cfe-commits


@@ -298,3 +298,19 @@ multiclass ZAAddSub {
 
 defm SVADD : ZAAddSub<"add">;
 defm SVSUB : ZAAddSub<"sub">;
+
+//
+// Outer produce and accumulate/subtract
+//
+
+let TargetGuard = "sme2" in {
+  def SVSMOPA  : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "s", MergeNone, 
"aarch64_sme_smopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+  def SVUSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "Us", MergeNone, 
"aarch64_sme_umopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+
+  def SVSMOPS  : Inst<"svmops_za32[_{d}]_m", "viPPdd", "s", MergeNone, 
"aarch64_sme_smops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+  def SVUSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "Us", MergeNone, 
"aarch64_sme_umops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+

kmclaughlin-arm wrote:

I think the "Outer product and accumulate/subtract" header applies to all of 
these, including the bmopa/s builtins? I've fixed the typo though :)

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


[clang] [Clang][SME2] Add outer product and accumulate/subtract builtins (PR #71176)

2023-11-24 Thread Kerry McLaughlin via cfe-commits

https://github.com/kmclaughlin-arm updated 
https://github.com/llvm/llvm-project/pull/71176

>From c975abe9015d5c9f5f7c7388101900cbcf738ab6 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin 
Date: Thu, 2 Nov 2023 17:02:32 +
Subject: [PATCH 1/3] [Clang][SME2] Add outer product and accumulate/subtract
 builtins

Adds the following SME2 builtins:
 - svmop(a|s)_za32,
 - svbmop(a|s)_za32

See https://github.com/ARM-software/acle/pull/217
---
 clang/include/clang/Basic/arm_sme.td  |  16 ++
 .../aarch64-sme2-intrinsics/acle_sme2_mop.c   | 170 ++
 .../aarch64-sme2-intrinsics/acle_sme2_imm.cpp |  18 ++
 3 files changed, 204 insertions(+)
 create mode 100644 clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mop.c
 create mode 100644 clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp

diff --git a/clang/include/clang/Basic/arm_sme.td 
b/clang/include/clang/Basic/arm_sme.td
index b5655afdf419ecf..1f88b39468105f2 100644
--- a/clang/include/clang/Basic/arm_sme.td
+++ b/clang/include/clang/Basic/arm_sme.td
@@ -298,3 +298,19 @@ multiclass ZAAddSub {
 
 defm SVADD : ZAAddSub<"add">;
 defm SVSUB : ZAAddSub<"sub">;
+
+//
+// Outer produce and accumulate/subtract
+//
+
+let TargetGuard = "sme2" in {
+  def SVSMOPA  : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "s", MergeNone, 
"aarch64_sme_smopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+  def SVUSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "Us", MergeNone, 
"aarch64_sme_umopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+
+  def SVSMOPS  : Inst<"svmops_za32[_{d}]_m", "viPPdd", "s", MergeNone, 
"aarch64_sme_smops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+  def SVUSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "Us", MergeNone, 
"aarch64_sme_umops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+
+  def SVBMOPA : Inst<"svbmopa_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, 
"aarch64_sme_bmopa_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+
+  def SVBMOPS : Inst<"svbmops_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, 
"aarch64_sme_bmops_za32", [IsSharedZA, IsStreaming], [ImmCheck<0, 
ImmCheck0_3>]>;
+}
diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mop.c 
b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mop.c
new file mode 100644
index 000..bb804a523c449d3
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_mop.c
@@ -0,0 +1,170 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | 
opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x 
c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s 
-check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve -S -disable-O0-optnone -Werror -Wall 
-emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu 
-target-feature +sme2 -target-feature +sve -S -disable-O0-optnone -Werror -Wall 
-emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | 
FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 
-target-feature +sve -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+#include 
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// MOPA
+
+// CHECK-LABEL: @test_svmopa_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CHECK-NEXT:tail call void @llvm.aarch64.sme.smopa.za32.nxv8i16(i32 3, 
 [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CHECK-NEXT:ret void
+//
+// CPP-CHECK-LABEL: @_Z15test_svmopa_s16u10__SVBool_tS_u11__SVInt16_tS0_(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:[[TMP0:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PN:%.*]])
+// CPP-CHECK-NEXT:[[TMP1:%.*]] = tail call  
@llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PM:%.*]])
+// CPP-CHECK-NEXT:tail call void @llvm.aarch64.sme.smopa.za32.nxv8i16(i32 
3,  [[TMP0]],  [[TMP1]],  
[[ZN:%.*]],  [[ZM:%.*]])
+// CPP-CHECK-NEXT:ret void
+//
+void test_svmopa_s16(svbool_t pn, svbool_t pm, svint16_t zn, svint16_t zm) {
+  SVE_ACLE_FUNC(svmopa_za32,_s16,_m,)(3, 

[flang] [clang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Kiran Chandramohan via cfe-commits

https://github.com/kiranchandramohan approved this pull request.

LG. Thanks for the patch and the changes.

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


[libc] [libcxx] [lld] [clang] [llvm] [compiler-rt] [flang] Fix ISel crash when lowering BUILD_VECTOR (PR #73186)

2023-11-24 Thread David Li via cfe-commits


@@ -986,15 +1003,15 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
 case X86ISD::VBROADCAST: {
   MVT VT = N->getSimpleValueType(0);
   // Emulate v32i16/v64i8 broadcast without BWI.
-  if (!Subtarget->hasBWI() && (VT == MVT::v32i16 || VT == MVT::v64i8)) {
-MVT NarrowVT = VT == MVT::v32i16 ? MVT::v16i16 : MVT::v32i8;
+  if (!Subtarget->hasBWI() && needBWI(VT)) {
+MVT NarrowVT = getNarrowType(VT);
 SDLoc dl(N);
 SDValue NarrowBCast =
 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT, 
N->getOperand(0));
 SDValue Res =
 CurDAG->getNode(ISD::INSERT_SUBVECTOR, dl, VT, 
CurDAG->getUNDEF(VT),
 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
-unsigned Index = VT == MVT::v32i16 ? 16 : 32;
+unsigned Index = getInsertIndex(VT);

david-xl wrote:

Comments addressed. PTAL

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


[clang] [flang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Michael Klemm via cfe-commits


@@ -0,0 +1,15 @@
+! UNSUPPORTED: system-windows
+
+! RUN: %flang -x ir -o %t.c-object -c %S/Inputs/main_dupes.ll
+! RUN: %flang -o %t -c %s
+! RUN: not %flang -o %t.exe %t %t.c-object 2>&1

mjklemm wrote:

I'd actually prefer to have a separate test for this, as a working test is any 
other test that actually produces an executable.

If you insist :-), then I'd even go and change the test from testing for a 
duplicate of main to a general link time test that tests both a successful link 
and the failing one that I'm after.

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


[clang] [flang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Michael Klemm via cfe-commits

mjklemm wrote:

> LGTM, thank you for taking care of this 
> 
> Dare I ask - what's "dupes"? I only found 
> [dupe](https://dictionary.cambridge.org/dictionary/english/dupe). Also, 
> please wait for @kiranchandramohan to approve before merging this :)

I used "dupes" in the sense of being fooled.  I can of course still change the 
name to something like "main_linktime_duplicate.f90" or the likes.

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


[clang] [clang][ASTMatcher] Add matchers for CXXFoldExpr (PR #71245)

2023-11-24 Thread Julian Schmidt via cfe-commits

5chmidti wrote:

@EugeneZelenko sorry for the direct ping, but I know you are one of the people 
that are active with labels (thanks btw).
Could you please reapply the `clang` (or maybe the `clang:frontend` is a better 
fit) label to this pr? A now fixed issue with the pr subscriber notification 
action meant that the notification for groups did not happen for this pr.

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


[clang] [flang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Andrzej Warzyński via cfe-commits

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


[clang] [flang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Andrzej Warzyński via cfe-commits


@@ -0,0 +1,15 @@
+! UNSUPPORTED: system-windows
+
+! RUN: %flang -x ir -o %t.c-object -c %S/Inputs/main_dupes.ll
+! RUN: %flang -o %t -c %s
+! RUN: not %flang -o %t.exe %t %t.c-object 2>&1

banach-space wrote:

[nit] You could add a "valid"/"working" compilation line to contrast it with 
the broken one. 

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


[flang] [clang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

2023-11-24 Thread Andrzej Warzyński via cfe-commits

https://github.com/banach-space approved this pull request.

LGTM, thank you for taking care of this  

Dare I ask - what's "dupes"?  I only found 
[dupe](https://dictionary.cambridge.org/dictionary/english/dupe). Also, please 
wait for @kiranchandramohan to approve before merging this :)

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


[clang-tools-extra] [llvm] [RISCV][Zba] Optimize mul with SH*ADD (PR #68144)

2023-11-24 Thread Craig Topper via cfe-commits


@@ -983,6 +983,1299 @@ define i64 @mul81(i64 %a) {
   ret i64 %c
 }
 
+
+define i64 @mul153(i64 %a) {
+; RV64I-LABEL: mul153:

topperc wrote:

llvm-mca doesn't think this is an improvement for sifive-x280 
https://godbolt.org/z/6ahP11xrq

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


[clang] [llvm] [lld] [compiler-rt] [libcxx] [libc] [flang] Fix ISel crash when lowering BUILD_VECTOR (PR #73186)

2023-11-24 Thread Simon Pilgrim via cfe-commits


@@ -986,15 +1003,15 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
 case X86ISD::VBROADCAST: {
   MVT VT = N->getSimpleValueType(0);
   // Emulate v32i16/v64i8 broadcast without BWI.
-  if (!Subtarget->hasBWI() && (VT == MVT::v32i16 || VT == MVT::v64i8)) {
-MVT NarrowVT = VT == MVT::v32i16 ? MVT::v16i16 : MVT::v32i8;
+  if (!Subtarget->hasBWI() && needBWI(VT)) {
+MVT NarrowVT = getNarrowType(VT);
 SDLoc dl(N);
 SDValue NarrowBCast =
 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT, 
N->getOperand(0));
 SDValue Res =
 CurDAG->getNode(ISD::INSERT_SUBVECTOR, dl, VT, 
CurDAG->getUNDEF(VT),
 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
-unsigned Index = VT == MVT::v32i16 ? 16 : 32;
+unsigned Index = getInsertIndex(VT);

RKSimon wrote:

unsigned Index = NarrowVT.getVectorMinNumElements()

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


[libcxx] [flang] [clang] [llvm] [libc] [compiler-rt] [lld] Fix ISel crash when lowering BUILD_VECTOR (PR #73186)

2023-11-24 Thread Simon Pilgrim via cfe-commits


@@ -881,6 +881,23 @@ static bool isEndbrImm64(uint64_t Imm) {
   return false;
 }
 
+static bool needBWI(MVT VT) {
+  return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
+}
+
+static MVT getNarrowType(MVT VT) {
+  if (VT == MVT::v32i16)
+return MVT::v16i16;
+  if (VT == MVT::v32f16)
+return MVT::v16f16;
+  assert(VT == MVT::v64i8 && "Unexpected VT");
+  return MVT::v32i8;
+}

RKSimon wrote:

This can be done with:
```c
assert(needBWI(VT) && "Unexpected VT");
return VT.getHalfNumVectorElementsVT();
```
or we can just use getHalfNumVectorElementsVT directly and avoid the 
getNarrowType helper

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


[llvm] [lld] [compiler-rt] [libcxx] [libc] [flang] [clang] Fix ISel crash when lowering BUILD_VECTOR (PR #73186)

2023-11-24 Thread Simon Pilgrim via cfe-commits

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


[flang] [compiler-rt] [lld] [llvm] [libc] [clang] [libcxx] Fix ISel crash when lowering BUILD_VECTOR (PR #73186)

2023-11-24 Thread Simon Pilgrim via cfe-commits

https://github.com/RKSimon commented:

Just a couple of minors

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


[clang] [clang] Add missing LinkageSpec case to getCursorKindForDecl (PR #72401)

2023-11-24 Thread Shivam Gupta via cfe-commits

xgupta wrote:

> By the way, I don't have permission to merge, so feel free to do it when you 
> think it's ready.

Thanks for the contribution.


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


[clang] [clang] Add missing LinkageSpec case to getCursorKindForDecl (PR #72401)

2023-11-24 Thread Shivam Gupta via cfe-commits

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


[clang] 7091ca1 - [clang] Add missing LinkageSpec case to getCursorKindForDecl (#72401)

2023-11-24 Thread via cfe-commits

Author: Sebastian Poeplau
Date: 2023-11-24T21:41:17+05:30
New Revision: 7091ca1ae3a87479b6febdf1c3a324d707c633d9

URL: 
https://github.com/llvm/llvm-project/commit/7091ca1ae3a87479b6febdf1c3a324d707c633d9
DIFF: 
https://github.com/llvm/llvm-project/commit/7091ca1ae3a87479b6febdf1c3a324d707c633d9.diff

LOG: [clang] Add missing LinkageSpec case to getCursorKindForDecl (#72401)

The LinkageSpec case was omitted, and there is a declared CXCursor_Kind
for it. Adapt the testsuite drivers to print mangled names for
declarations with extern linkage. Also update the test baseline for the
recursive-cxx-member-calls.cpp test.

Co-authored-by: Matthieu Eyraud 

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaCodeComplete.cpp
clang/test/Index/recursive-cxx-member-calls.cpp
clang/tools/c-index-test/c-index-test.c

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 362ce410356719b..0ce15169d49bcce 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -938,6 +938,8 @@ libclang
 
 
 - Exposed arguments of ``clang::annotate``.
+- ``clang::getCursorKindForDecl`` now recognizes linkage specifications such as
+  ``extern "C"`` and reports them as ``CXCursor_LinkageSpec``.
 
 Static Analyzer
 ---

diff  --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 3355336d8c2c816..6169144ef1c2d48 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -4165,6 +4165,9 @@ CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
   case Decl::Concept:
 return CXCursor_ConceptDecl;
 
+  case Decl::LinkageSpec:
+return CXCursor_LinkageSpec;
+
   default:
 if (const auto *TD = dyn_cast(D)) {
   switch (TD->getTagKind()) {

diff  --git a/clang/test/Index/recursive-cxx-member-calls.cpp 
b/clang/test/Index/recursive-cxx-member-calls.cpp
index 09f3f414194c565..be908c506e74769 100644
--- a/clang/test/Index/recursive-cxx-member-calls.cpp
+++ b/clang/test/Index/recursive-cxx-member-calls.cpp
@@ -216,9 +216,9 @@ AttributeList::Kind AttributeList::getKind(const 
IdentifierInfo * Name) {
 // CHECK-tokens: Punctuation: "}" [4:63 - 4:64] ClassTemplate=pair:4:44 
(Definition)
 // CHECK-tokens: Punctuation: ";" [4:64 - 4:65] Namespace=std:3:11 (Definition)
 // CHECK-tokens: Punctuation: "}" [5:1 - 5:2] Namespace=std:3:11 (Definition)
-// CHECK-tokens: Keyword: "extern" [6:1 - 6:7]
-// CHECK-tokens: Literal: ""C"" [6:8 - 6:11] UnexposedDecl=:6:8 (Definition)
-// CHECK-tokens: Punctuation: "{" [6:12 - 6:13] UnexposedDecl=:6:8 (Definition)
+// CHECK-tokens: Keyword: "extern" [6:1 - 6:7] LinkageSpec=:6:8 (Definition)
+// CHECK-tokens: Literal: ""C"" [6:8 - 6:11] LinkageSpec=:6:8 (Definition)
+// CHECK-tokens: Punctuation: "{" [6:12 - 6:13] LinkageSpec=:6:8 (Definition)
 // CHECK-tokens: Keyword: "int" [7:3 - 7:6] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Identifier: "memcmp" [7:7 - 7:13] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Punctuation: "(" [7:13 - 7:14] FunctionDecl=memcmp:7:7
@@ -232,7 +232,7 @@ AttributeList::Kind AttributeList::getKind(const 
IdentifierInfo * Name) {
 // CHECK-tokens: Punctuation: "," [7:40 - 7:41] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Identifier: "size_t" [7:42 - 7:48] TypeRef=size_t:2:25
 // CHECK-tokens: Punctuation: ")" [7:48 - 7:49] FunctionDecl=memcmp:7:7
-// CHECK-tokens: Punctuation: ";" [7:49 - 7:50] UnexposedDecl=:6:8 (Definition)
+// CHECK-tokens: Punctuation: ";" [7:49 - 7:50] LinkageSpec=:6:8 (Definition)
 // CHECK-tokens: Identifier: "size_t" [8:3 - 8:9] TypeRef=size_t:2:25
 // CHECK-tokens: Identifier: "strlen" [8:10 - 8:16] FunctionDecl=strlen:8:10
 // CHECK-tokens: Punctuation: "(" [8:16 - 8:17] FunctionDecl=strlen:8:10
@@ -1532,7 +1532,7 @@ AttributeList::Kind AttributeList::getKind(const 
IdentifierInfo * Name) {
 // CHECK: 4:20: TemplateTypeParameter=_T1:4:20 (Definition) Extent=[4:14 - 
4:23]
 // CHECK: 4:31: TemplateTypeParameter=_T2:4:31 (Definition) Extent=[4:25 - 
4:34]
 // CHECK: 4:55: FieldDecl=second:4:55 (Definition) Extent=[4:51 - 4:61]
-// CHECK: 6:8: UnexposedDecl=:6:8 (Definition) Extent=[6:1 - 9:2]
+// CHECK: 6:8: LinkageSpec=:6:8 (Definition) Extent=[6:1 - 9:2]
 // CHECK: 7:7: FunctionDecl=memcmp:7:7 Extent=[7:3 - 7:49]
 // CHECK: 7:26: ParmDecl=:7:26 (Definition) Extent=[7:14 - 7:26]
 // CHECK: 7:40: ParmDecl=:7:40 (Definition) Extent=[7:28 - 7:40]

diff  --git a/clang/tools/c-index-test/c-index-test.c 
b/clang/tools/c-index-test/c-index-test.c
index 9d66a22f3b43b55..2c0c9cb8eb5e42f 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1838,6 +1838,8 @@ static enum CXChildVisitResult PrintMangledName(CXCursor 
cursor, CXCursor p,
   CXString MangledName;
   if (clang_isUnexposed(clang_getCursorKind(cursor)))
 return CXChildVisit_Recurse;
+  if 

[clang] [Clang] Fix `-Wdocumentation` warning (NFC) (PR #73243)

2023-11-24 Thread Egor Zhdan via cfe-commits

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


[clang] 18a5ca1 - [Clang] Fix `-Wdocumentation` warning (NFC)

2023-11-24 Thread via cfe-commits

Author: Egor Zhdan
Date: 2023-11-24T15:41:37Z
New Revision: 18a5ca14d16e6e5142fc5527accdfb10c1a22820

URL: 
https://github.com/llvm/llvm-project/commit/18a5ca14d16e6e5142fc5527accdfb10c1a22820
DIFF: 
https://github.com/llvm/llvm-project/commit/18a5ca14d16e6e5142fc5527accdfb10c1a22820.diff

LOG: [Clang] Fix `-Wdocumentation` warning (NFC)

```
llvm-project/clang/include/clang/AST/OpenMPClause.h:7762:14: warning: parameter 
'Modifier' not found in the function declaration [-Wdocumentation]
  /// \param Modifier The modifier applied to 'order' clause.
 ^~~~
llvm-project/clang/include/clang/AST/OpenMPClause.h:7762:14: note: did you mean 
'M'?
  /// \param Modifier The modifier applied to 'order' clause.
```

Added: 


Modified: 
clang/include/clang/AST/OpenMPClause.h

Removed: 




diff  --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index 549f12e87df597a..51155e63dcb8f7d 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -7776,10 +7776,10 @@ class OMPOrderClause final : public OMPClause {
   /// \param MLoc Location of the modifier
   OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc,
  SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, OpenMPOrderClauseModifier M,
+ SourceLocation EndLoc, OpenMPOrderClauseModifier Modifier,
  SourceLocation MLoc)
   : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc),
-LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc), Modifier(M),
+LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc), Modifier(Modifier),
 ModifierKwLoc(MLoc) {}
 
   /// Build an empty clause.



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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Balázs Kéri via cfe-commits

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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Balázs Kéri via cfe-commits


@@ -774,26 +780,45 @@ void StreamChecker::evalFgetcFputc(const FnDescription 
*Desc,
 
   // `fgetc` returns the read character on success, otherwise returns EOF.
   // `fputc` returns the written character on success, otherwise returns EOF.
+  // `fputs` returns a non negative value on sucecess, otherwise returns EOF.
 
-  // Generate a transition for the success state of fputc.
+  SValBuilder  = C.getSValBuilder();
+  auto  = C.getASTContext();
   if (!IsRead) {
-std::optional PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
+// Generddate a transition for the success state of `fputc`.
+if (SingleChar) {
+  std::optional PutVal = Call.getArgSVal(0).getAs();
+  if (!PutVal)
+return;
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), *PutVal);
+  StateNotFailed = StateNotFailed->set(
+  StreamSym, StreamState::getOpened(Desc));
+  C.addTransition(StateNotFailed);
+}
+// Generddate a transition for the success state of `fputs`.
+else {
+  NonLoc RetVal = makeRetVal(C, CE).castAs();
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), RetVal);
+  auto Cond =
+  SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ASTC.IntTy),
+SVB.getConditionType())
+  .getAs();
+  if (!Cond)
+return;
+  StateNotFailed = StateNotFailed->assume(*Cond, true);
+  if (!StateNotFailed)
+return;
+  C.addTransition(StateNotFailed);
+}

balazske wrote:

This function is becoming too large. Here almost all code for `fputs` is in a 
new branch and really there are 4 condition branches for all 4 functions (if 
`fgets` is added) with not much common code. It looks better to make an 
`evalFputX` and `evalFgetX` function (but `fgets` can be too much different 
than the other). Functions for the common code at begin and end of these `eval` 
functions (that can be reused by the others too) could be good too (and 
separate eval functions for all get and put cases), but this belongs into a 
separate PR. Probably I can improve the code, my next plans contain anyway to 
work with `StreamChecker`.

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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Balázs Kéri via cfe-commits


@@ -50,6 +50,7 @@ size_t fread(void *restrict, size_t, size_t, FILE *restrict);
 size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
 int fgetc(FILE *stream);
 int fputc(int ch, FILE *stream);
+int fputs(const char *str, FILE *stream);

balazske wrote:

The exact POSIX declaration is `int fputs(const char *restrict s, FILE 
*restrict stream)`.

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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread Balázs Kéri via cfe-commits

https://github.com/balazske requested changes to this pull request.


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


[clang] [Clang] Fix `-Wdocumentation` warning (NFC) (PR #73243)

2023-11-24 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

LGTM

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


[clang] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2 (PR #72107)

2023-11-24 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


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


[clang] [clang][analyzer] Support `fputs` in the StreamChecker (PR #73335)

2023-11-24 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-static-analyzer-1

@llvm/pr-subscribers-clang

Author: Ben Shi (benshi001)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/73335.diff


4 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (+43-18) 
- (modified) clang/test/Analysis/Inputs/system-header-simulator.h (+1) 
- (modified) clang/test/Analysis/stream-error.c (+18) 
- (modified) clang/test/Analysis/stream.c (+6) 


``diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 8eca989d7bcdea4..0e85f1fd0655143 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -252,10 +252,16 @@ class StreamChecker : public Checker PutVal = Call.getArgSVal(0).getAs();
-if (!PutVal)
-  return;
-ProgramStateRef StateNotFailed =
-State->BindExpr(CE, C.getLocationContext(), *PutVal);
-StateNotFailed =
-StateNotFailed->set(StreamSym, 
StreamState::getOpened(Desc));
-C.addTransition(StateNotFailed);
+// Generddate a transition for the success state of `fputc`.
+if (SingleChar) {
+  std::optional PutVal = Call.getArgSVal(0).getAs();
+  if (!PutVal)
+return;
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), *PutVal);
+  StateNotFailed = StateNotFailed->set(
+  StreamSym, StreamState::getOpened(Desc));
+  C.addTransition(StateNotFailed);
+}
+// Generddate a transition for the success state of `fputs`.
+else {
+  NonLoc RetVal = makeRetVal(C, CE).castAs();
+  ProgramStateRef StateNotFailed =
+  State->BindExpr(CE, C.getLocationContext(), RetVal);
+  auto Cond =
+  SVB.evalBinOp(State, BO_GE, RetVal, SVB.makeZeroVal(ASTC.IntTy),
+SVB.getConditionType())
+  .getAs();
+  if (!Cond)
+return;
+  StateNotFailed = StateNotFailed->assume(*Cond, true);
+  if (!StateNotFailed)
+return;
+  C.addTransition(StateNotFailed);
+}
   }
-  // Generate a transition for the success state of fgetc.
+  // Generate a transition for the success state of `fgetc`.
   // If we know the state to be FEOF at fgetc, do not add a success state.
   else if (OldSS->ErrorState != ErrorFEof) {
 NonLoc RetVal = makeRetVal(C, CE).castAs();
 ProgramStateRef StateNotFailed =
 State->BindExpr(CE, C.getLocationContext(), RetVal);
-SValBuilder  = C.getSValBuilder();
-auto  = C.getASTContext();
 // The returned 'unsigned char' of `fgetc` is converted to 'int',
 // so we need to check if it is in range [0, 255].
 auto CondLow =
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index fc57e8bdc3d30c3..351de8c132fecc7 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -50,6 +50,7 @@ size_t fread(void *restrict, size_t, size_t, FILE *restrict);
 size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
 int fgetc(FILE *stream);
 int fputc(int ch, FILE *stream);
+int fputs(const char *str, FILE *stream);
 int fseek(FILE *__stream, long int __off, int __whence);
 long int ftell(FILE *__stream);
 void rewind(FILE *__stream);
diff --git a/clang/test/Analysis/stream-error.c 
b/clang/test/Analysis/stream-error.c
index 38e6b77b9bb5053..04e6b834fe9d4b5 100644
--- a/clang/test/Analysis/stream-error.c
+++ b/clang/test/Analysis/stream-error.c
@@ -141,6 +141,24 @@ void error_fputc(void) {
   fputc('A', F); // expected-warning {{Stream might be already closed}}
 }
 
+void error_fputs(void) {
+  FILE *F = tmpfile();
+  if (!F)
+return;
+  int Ret = fputs("XYZ", F);
+  if (Ret >= 0) {
+clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}}
+fputs("QWD", F);   // no-warning
+  } else {
+clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}}
+clang_analyzer_eval(ferror(F));  // expected-warning {{TRUE}}
+clang_analyzer_eval(feof(F));// expected-warning {{FALSE}}
+fputs("QWD", F); // expected-warning {{might be 
'indeterminate'}}
+  }
+  fclose(F);
+  fputs("ABC", F);   // expected-warning {{Stream might be 
already closed}}
+}
+
 void freadwrite_zerosize(FILE *F) {
   size_t Ret;
   Ret = fwrite(0, 1, 0, F);
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index a7ee9982478bb96..b0f39af8eb2f3a3 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -26,6 +26,12 @@ void check_fputc(void) {
   fclose(fp);
 }
 
+void check_fputs(void) {
+  FILE *fp = tmpfile();
+  fputs("ABC", fp); // expected-warning {{Stream pointer might be NULL}}
+  fclose(fp);
+}
+
 void check_fseek(void) {
   FILE *fp = tmpfile();
   fseek(fp, 

[clang] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2 (PR #72107)

2023-11-24 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


https://github.com/DonatNagyE updated 
https://github.com/llvm/llvm-project/pull/72107

>From ab102e949994a4462382e4c10c0153d61fb00306 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Mon, 13 Nov 2023 11:16:26 +0100
Subject: [PATCH 1/3] [analyzer] Switch to PostStmt callbacks in ArrayBoundV2

...instead of the currently used, more abstract Location callback. The
main advantage of this change is that after it the checker will check
`array[index].field` while the previous implementation ignored this
situation (because here the ElementRegion is wrapped in a FieldRegion
object). This improvement fixes PR #70187.

Note that after this change `[idx]` will be handled as an access
to the `idx`th element of `array`, which is technically incorrect but
matches the programmer intuitions. In my opinion it's more helpful if
the report points to the source location where the indexing happens
(instead of the location where a pointer is finally dereferenced).

This change introduces false positives in the exceptional corner case
when the past-the-end pointer of an array is formed as `[length]`. I
think this is just unimportant pedantery (because it's cleaner to write
the past-the-end pointer as `(arr+length)` and that form isn't affected
by this checker), but if it does appear in real code, then we could
introduce a special case for it.

In addition to this primary improvement, this change tweaks the message
for the tainted index/offset case (using the more concrete information
that's available now) and clarifies/improves a few testcases.

The main change of this commit (replacing `check::Location` with
`check::PostStmt<...>` callbacks) was already proposed in my change
https://reviews.llvm.org/D150446 and https://reviews.llvm.org/D159107 by
@steakhal. Those reviews were both abandoned, but the issues were
unrelated to the change that is introduced in this PR.
---
 .../Checkers/ArrayBoundCheckerV2.cpp  | 96 ---
 .../test/Analysis/out-of-bounds-diagnostics.c | 74 --
 .../test/Analysis/taint-diagnostic-visitor.c  |  4 +-
 3 files changed, 129 insertions(+), 45 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index ffc7236d1e2551a..ef3ae42d57c6e88 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -34,20 +34,37 @@ using llvm::formatv;
 namespace {
 enum OOB_Kind { OOB_Precedes, OOB_Exceeds, OOB_Taint };
 
-class ArrayBoundCheckerV2 :
-public Checker {
+struct Messages {
+  std::string Short, Full;
+};
+
+class ArrayBoundCheckerV2 : public Checker,
+   check::PostStmt,
+   check::PostStmt> {
   BugType BT{this, "Out-of-bound access"};
   BugType TaintBT{this, "Out-of-bound access", categories::TaintedData};
 
+  void performCheck(const Expr *E, CheckerContext ) const;
+
   void reportOOB(CheckerContext , ProgramStateRef ErrorState, OOB_Kind Kind,
- NonLoc Offset, std::string RegName, std::string Msg) const;
+ NonLoc Offset, Messages Msgs) const;
 
   static bool isFromCtypeMacro(const Stmt *S, ASTContext );
 
 public:
-  void checkLocation(SVal l, bool isLoad, const Stmt *S,
- CheckerContext ) const;
+  void checkPostStmt(const ArraySubscriptExpr *E, CheckerContext ) const {
+performCheck(E, C);
+  }
+  void checkPostStmt(const UnaryOperator *E, CheckerContext ) const {
+if (E->getOpcode() == UO_Deref)
+  performCheck(E, C);
+  }
+  void checkPostStmt(const MemberExpr *E, CheckerContext ) const {
+if (E->isArrow())
+  performCheck(E->getBase(), C);
+  }
 };
+
 } // anonymous namespace
 
 /// For a given Location that can be represented as a symbolic expression
@@ -217,16 +234,19 @@ static std::string getShortMsg(OOB_Kind Kind, std::string 
RegName) {
   return formatv(ShortMsgTemplates[Kind], RegName);
 }
 
-static std::string getPrecedesMsg(std::string RegName, NonLoc Offset) {
+static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) {
+  std::string RegName = getRegionName(Region);
   SmallString<128> Buf;
   llvm::raw_svector_ostream Out(Buf);
   Out << "Access of " << RegName << " at negative byte offset";
   if (auto ConcreteIdx = Offset.getAs())
 Out << ' ' << ConcreteIdx->getValue();
-  return std::string(Buf);
+  return {getShortMsg(OOB_Precedes, RegName), std::string(Buf)};
 }
-static std::string getExceedsMsg(ASTContext , std::string RegName,
- NonLoc Offset, NonLoc Extent, SVal Location) {
+
+static Messages getExceedsMsgs(ASTContext , const SubRegion *Region,
+   NonLoc Offset, NonLoc Extent, SVal Location) {
+  std::string RegName = getRegionName(Region);
   const auto 

  1   2   >