[clang] 67f08bf - [Clang] [Sema] Ignore invalid multiversion function redeclarations

2022-09-13 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-09-13T20:12:09Z
New Revision: 67f08bf1bfa85fcdc1d91a3e6cce703e94611244

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

LOG: [Clang] [Sema] Ignore invalid multiversion function redeclarations

If a redeclaration of a multiversion function is invalid,
it may be in a broken condition (for example, missing an important
attribute). We shouldn't analyze invalid redeclarations.

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

Reviewed By: tahonermann

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

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/attr-target-mv.c

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 58774c0fa44a3..e4bd827b38d39 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11082,11 +11082,11 @@ static bool CheckMultiVersionAdditionalDecl(
   bool MayNeedOverloadableChecks =
   AllowOverloadingOfFunction(Previous, S.Context, NewFD);
 
-  // Next, check ALL non-overloads to see if this is a redeclaration of a
-  // previous member of the MultiVersion set.
+  // Next, check ALL non-invalid non-overloads to see if this is a 
redeclaration
+  // of a previous member of the MultiVersion set.
   for (NamedDecl *ND : Previous) {
 FunctionDecl *CurFD = ND->getAsFunction();
-if (!CurFD)
+if (!CurFD || CurFD->isInvalidDecl())
   continue;
 if (MayNeedOverloadableChecks &&
 S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules))

diff  --git a/clang/test/Sema/attr-target-mv.c 
b/clang/test/Sema/attr-target-mv.c
index b02b13079163b..8218771275e1b 100644
--- a/clang/test/Sema/attr-target-mv.c
+++ b/clang/test/Sema/attr-target-mv.c
@@ -52,6 +52,15 @@ int __attribute__((target("default"))) redef2(void) { return 
1;}
 // expected-note@-2 {{previous definition is here}}
 int __attribute__((target("default"))) redef2(void) { return 1;}
 
+int redef3(void) { return 1; }
+// expected-warning@+4 {{attribute declaration must precede definition}}
+// expected-note@-2 {{previous definition is here}}
+// expected-error@+2 {{redefinition of 'redef3'}}
+// expected-note@-4 {{previous definition is here}}
+int __attribute__((target("default"))) redef3(void) { return 1; }
+// allow this, since we don't complain about more than one redefinition
+int __attribute__((target("sse4.2"))) redef3(void) { return 1; }
+
 int __attribute__((target("sse4.2"))) mv_after_use(void) { return 1; }
 int use3(void) {
   return mv_after_use();



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


[clang] 3587b15 - [Clang] [P2025] More exhaustive tests for NRVO

2022-03-16 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-03-17T03:58:40+03:00
New Revision: 3587b15abe683f164093f8d057e921f913572007

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

LOG: [Clang] [P2025] More exhaustive tests for NRVO

This is a preliminary patch ahead of D119792 (I'll rebase that one on top of 
this).
This shows what Clang's _current_ behaviour is for calculating NRVO in various
common cases. Then, in D119792 (and future patches), I'll be able to demostrate
exactly how LLVM IR for each of these cases changes.

Reviewed By: Quuxplusone

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

Added: 


Modified: 
clang/test/CodeGenCXX/nrvo.cpp

Removed: 




diff  --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp
index c9428fd8887db..542d6d98b0a6c 100644
--- a/clang/test/CodeGenCXX/nrvo.cpp
+++ b/clang/test/CodeGenCXX/nrvo.cpp
@@ -1,13 +1,14 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | 
FileCheck %s
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 
-fcxx-exceptions -fexceptions -std=c++03 -o - %s | FileCheck 
--check-prefixes=CHECK-EH,CHECK-EH-03 %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 
-fcxx-exceptions -fexceptions -std=c++11 -o - %s | FileCheck 
--check-prefixes=CHECK-EH,CHECK-EH-11 %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 
-fcxx-exceptions -fexceptions -std=c++11 -DCXX11 -o - %s | FileCheck 
--check-prefixes=CHECK-EH,CHECK-EH-11 %s
 
 // Test code generation for the named return value optimization.
 class X {
 public:
   X();
   X(const X&);
+  X(const volatile X &);
   ~X();
 };
 
@@ -19,6 +20,9 @@ template struct Y {
   }
 };
 
+void ConsumeX(X x);
+extern X OuterX;
+
 // CHECK-LABEL: @_Z5test0v(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 
dereferenceable(1) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]]
@@ -29,10 +33,9 @@ template struct Y {
 // CHECK-EH-NEXT:call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 
dereferenceable(1) [[AGG_RESULT:%.*]])
 // CHECK-EH-NEXT:ret void
 //
-X test0() {
+X test0() { // http://wg21.link/p2025r2#ex-2
   X x;
-
-  return x;
+  return x; // NRVO happens
 }
 
 // CHECK-LABEL: @_Z5test1b(
@@ -48,8 +51,8 @@ X test0() {
 X test1(bool B) {
   X x;
   if (B)
-return (x);
-  return x;
+return (x); // NRVO happens
+  return x; // NRVO happens
 }
 
 // CHECK-LABEL: @_Z5test2b(
@@ -155,13 +158,11 @@ X test1(bool B) {
 // CHECK-EH-11-NEXT:resume { i8*, i32 } [[DOTPN]]
 //
 X test2(bool B) {
-  // No NRVO.
-
   X x;
   X y;
   if (B)
-return y;
-  return x;
+return y; // NRVO is impossible
+  return x;   // NRVO is impossible
 }
 
 // CHECK-LABEL: @_Z5test3b(
@@ -242,14 +243,13 @@ X test2(bool B) {
 // CHECK-EH-11:   return:
 // CHECK-EH-11-NEXT:ret void
 //
-X test3(bool B) {
+X test3(bool B) { // http://wg21.link/p2025r2#ex-4
   if (B) {
 X y;
-return y;
+return y; // NRVO happens
   }
-  // FIXME: we should NRVO this variable too.
   X x;
-  return x;
+  return x; // FIXME: NRVO could happen, but doesn't
 }
 
 extern "C" void exit(int) throw();
@@ -291,7 +291,7 @@ X test4(bool B) {
   {
 X x;
 if (B)
-  return x;
+  return x; // NRVO happens
   }
   exit(1);
 }
@@ -407,11 +407,11 @@ void may_throw();
 // CHECK-EH-11-NEXT:call void @__clang_call_terminate(i8* [[TMP10]]) 
#[[ATTR8:[0-9]+]]
 // CHECK-EH-11-NEXT:unreachable
 //
-X test5() {
+X test5() { // http://wg21.link/p2025r2#ex-14
   try {
 may_throw();
   } catch (X x) {
-return x;
+return x; // FIXME: NRVO could happen, but doesn't
   }
 }
 #endif
@@ -476,7 +476,7 @@ X test5() {
 //
 X test6() {
   X a __attribute__((aligned(8)));
-  return a;
+  return a; // NRVO is impossible
 }
 
 // CHECK-LABEL: @_Z5test7b(
@@ -492,7 +492,7 @@ X test6() {
 X test7(bool b) {
   if (b) {
 X x;
-return x;
+return x; // NRVO happens
   }
   return X();
 }
@@ -510,10 +510,10 @@ X test7(bool b) {
 X test8(bool b) {
   if (b) {
 X x;
-return x;
+return x; // NRVO happens
   } else {
 X y;
-return y;
+return y; // NRVO happens
   }
 }
 
@@ -536,3 +536,1289 @@ X test8(bool b) {
 Y test9() {
   Y::f();
 }
+
+// CHECK-LABEL: @_Z6test10b(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[X:%.*]] = alloca [[CLASS_X:%.*]], align 1
+// CHECK-NEXT:[[TMP0:%.*]] = getelementptr inbounds [[CLASS_X]], %class.X* 
[[X]], i32 0, i32 0
+// CHECK-NEXT:call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull 
[[TMP0]]) #[[ATTR5]]
+// CHECK-NEXT:call void @_ZN1XC1Ev(%class.X* noundef nonnull align 1 
dereferenceable(1) [[X]]) #[[ATTR5]]
+// CHECK-NEXT:br i1 [[B

[clang-tools-extra] 6043520 - [clang-tidy] Don't check decltype return types in `readability-const-return-type`

2022-03-17 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-03-17T14:27:09+03:00
New Revision: 6043520c207269ccdbfe70e63ab48118d5735deb

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

LOG: [clang-tidy] Don't check decltype return types in 
`readability-const-return-type`

The checker removes `const`s that are superfluos and badly affect
readability. `decltype(auto)`/`decltype(expr)` are often const-qualified, but
have no effect on readability and usually can't stop being const-qualified
without significant code change.

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

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
index 814d3f266c5c3..ec92226773781 100644
--- a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
@@ -53,6 +53,18 @@ findConstToRemove(const FunctionDecl *Def,
 
 namespace {
 
+AST_MATCHER(QualType, isLocalConstQualified) {
+  return Node.isLocalConstQualified();
+}
+
+AST_MATCHER(QualType, isTypeOfType) {
+  return isa(Node.getTypePtr());
+}
+
+AST_MATCHER(QualType, isTypeOfExprType) {
+  return isa(Node.getTypePtr());
+}
+
 struct CheckResult {
   // Source range of the relevant `const` token in the definition being 
checked.
   CharSourceRange ConstRange;
@@ -95,10 +107,14 @@ static CheckResult checkDef(const clang::FunctionDecl *Def,
 
 void ConstReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
   // Find all function definitions for which the return types are `const`
-  // qualified.
+  // qualified, ignoring decltype types.
+  auto NonLocalConstType = qualType(
+  unless(isLocalConstQualified()),
+  anyOf(decltypeType(), autoType(), isTypeOfType(), isTypeOfExprType()));
   Finder->addMatcher(
-  functionDecl(returns(isConstQualified()),
-   anyOf(isDefinition(), cxxMethodDecl(isPure(
+  functionDecl(
+  returns(allOf(isConstQualified(), unless(NonLocalConstType))),
+  anyOf(isDefinition(), cxxMethodDecl(isPure(
   .bind("func"),
   this);
 }

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
index 70da965275650..a8642746145b8 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-const-return-type %t
+// RUN: %check_clang_tidy -std=c++14 %s readability-const-return-type %t
 
 //  p# = positive test
 //  n# = negative test
@@ -285,3 +285,40 @@ class PVDerive : public PVBase {
   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const int' is 
'const'-qualified at the top level, which may reduce code readability without 
improving const correctness
   // CHECK-NOT-FIXES: int getC() { return 1; }
 };
+
+// Don't warn about const auto types, because it may be impossible to make 
them non-const
+// without a significant semantics change. Since `auto` drops cv-qualifiers,
+// tests check `decltype(auto)`.
+decltype(auto) n16() {
+  static const int i = 42;
+  return i;
+}
+
+// Don't warn about `decltype()` types
+const int n17i = 1;
+decltype(n17i) n17() {
+  return 17;
+}
+
+// Do warn when on decltype types with the local const qualifier
+// `const decltype(auto)` won't compile, so check only `const decltype()`
+const decltype(n17i) n18() {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const decltype(n17i)
+  // CHECK-FIXES: decltype(n17i) n18() {
+  return 18;
+}
+
+// `volatile` modifier doesn't affect the checker
+volatile decltype(n17i) n19() {
+  return 19;
+}
+
+// Don't warn about `__typeof__()` types
+__typeof__(n17i) n20() {
+  return 20;
+}
+
+// Don't warn about `__typeof__(type)` types
+__typeof__(const int) n21() {
+  return 21;
+}



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


[clang-tools-extra] fc354d3 - [clang-tidy] Skip parentheses in `readability-make-member-function-const`

2022-03-21 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-03-21T14:18:17+03:00
New Revision: fc354d375232c22bbc13b80e4e339d8925ae2c70

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

LOG: [clang-tidy] Skip parentheses in `readability-make-member-function-const`

The checker should ignore parentheses when looking whether the
function should be marked as `const`.

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

Reviewed By: mgehre-amd, njames93

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp

clang-tools-extra/test/clang-tidy/checkers/readability-make-member-function-const.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
index 3e5b71fdd56b6..15ab39411 100644
--- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
@@ -66,6 +66,13 @@ class FindUsageOfThis : public 
RecursiveASTVisitor {
 return Parents.begin()->get();
   }
 
+  const Expr *getParentExprIgnoreParens(const Expr *E) {
+const Expr *Parent = getParent(E);
+while (isa_and_nonnull(Parent))
+  Parent = getParent(Parent);
+return Parent;
+  }
+
   bool VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *) {
 // An UnresolvedMemberExpr might resolve to a non-const non-static
 // member function.
@@ -140,7 +147,7 @@ class FindUsageOfThis : public 
RecursiveASTVisitor {
   return true;
 }
 
-const auto *Parent = getParent(Member);
+const auto *Parent = getParentExprIgnoreParens(Member);
 
 if (const auto *Cast = dyn_cast_or_null(Parent)) {
   // A read access to a member is safe when the member either
@@ -167,12 +174,12 @@ class FindUsageOfThis : public 
RecursiveASTVisitor {
   bool VisitCXXThisExpr(const CXXThisExpr *E) {
 Usage = Const;
 
-const auto *Parent = getParent(E);
+const auto *Parent = getParentExprIgnoreParens(E);
 
 // Look through deref of this.
 if (const auto *UnOp = dyn_cast_or_null(Parent)) {
   if (UnOp->getOpcode() == UO_Deref) {
-Parent = getParent(UnOp);
+Parent = getParentExprIgnoreParens(UnOp);
   }
 }
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability-make-member-function-const.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability-make-member-function-const.cpp
index 3591c169e332f..d454ad20fdd1b 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability-make-member-function-const.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability-make-member-function-const.cpp
@@ -40,6 +40,12 @@ struct A {
 return ConstM;
   }
 
+  int read_fields_in_parentheses() {
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 
'read_fields_in_parentheses' can be made const
+// CHECK-FIXES: {{^}}  int read_fields_in_parentheses() const {
+return (this)->M + (Struct.M) + ((this->ConstM));
+  }
+
   void call_const_member() {
 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'call_const_member' can 
be made const
 // CHECK-FIXES: {{^}}  void call_const_member() const {



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


[clang] 5b56763 - [Clang] Add __has_constexpr_builtin support

2022-10-21 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-21T11:23:10Z
New Revision: 5b567637e22bfa128514a5a9de7f3296423e8acd

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

LOG: [Clang] Add __has_constexpr_builtin support

The `__has_constexpr_builtin` macro can be used to check
whether the builtin in constant-evaluated by Clang frontend.

Reviewed By: aaron.ballman, shafik

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

Added: 


Modified: 
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Builtins.def
clang/include/clang/Basic/Builtins.h
clang/include/clang/Lex/Preprocessor.h
clang/lib/AST/ExprConstant.cpp
clang/lib/Lex/PPMacroExpansion.cpp
clang/test/Preprocessor/feature_tests.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c0f086554e245..c4a8f7e6b399c 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -66,6 +66,35 @@ It can be used like this:
   ``__has_builtin`` should not be used to detect support for a builtin macro;
   use ``#ifdef`` instead.
 
+``__has_constexpr_builtin``
+---
+
+This function-like macro takes a single identifier argument that is the name of
+a builtin function, a builtin pseudo-function (taking one or more type
+arguments), or a builtin template.
+It evaluates to 1 if the builtin is supported and can be constant evaluated or
+0 if not. It can be used for writing conditionally constexpr code like this:
+
+.. code-block:: c++
+
+  #ifndef __has_constexpr_builtin // Optional of course.
+#define __has_constexpr_builtin(x) 0  // Compatibility with non-clang 
compilers.
+  #endif
+
+  ...
+  #if __has_constexpr_builtin(__builtin_fmax)
+constexpr
+  #endif
+double money_fee(double amount) {
+return __builtin_fmax(amount * 0.03, 10.0);
+}
+  ...
+
+For example, ``__has_constexpr_builtin`` is used in libcxx's implementation of
+the  header file to conditionally make a function constexpr whenever
+the constant evaluation of the corresponding builtin (for example,
+``std::fmax`` calls ``__builtin_fmax``) is supported in Clang.
+
 .. _langext-__has_feature-__has_extension:
 
 ``__has_feature`` and ``__has_extension``

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e87a4eea552df..3f952334c3d9a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -360,6 +360,9 @@ Non-comprehensive list of changes in this release
   timestamp to be used in replacement of the current date and time in
   the ``__DATE__``, ``__TIME__``, and ``__TIMESTAMP__`` macros. See
   ``_.
+- Clang now supports ``__has_constexpr_builtin`` function-like macro that
+  evaluates to 1 if the builtin is supported and can be constant evaluated.
+  It can be used to writing conditionally constexpr code that uses builtins.
 
 New Compiler Flags
 --

diff  --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index b7c52a7292c8c..d9faafd8813ef 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -105,6 +105,7 @@
 //  C -> callback behavior: argument N is called with argument
 //  M_0, ..., M_k as payload
 //  z -> this is a function in (possibly-versioned) namespace std
+//  E -> this function can be constant evaluated by Clang frontend
 //  FIXME: gcc has nonnull
 
 #if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -121,16 +122,16 @@ BUILTIN(__builtin_atan2f, "fff"  , "Fne")
 BUILTIN(__builtin_atan2l, "LdLdLd", "Fne")
 BUILTIN(__builtin_atan2f128, "LLdLLdLLd", "Fne")
 BUILTIN(__builtin_abs  , "ii"  , "ncF")
-BUILTIN(__builtin_copysign, "ddd", "ncF")
-BUILTIN(__builtin_copysignf, "fff", "ncF")
+BUILTIN(__builtin_copysign, "ddd", "ncFE")
+BUILTIN(__builtin_copysignf, "fff", "ncFE")
 BUILTIN(__builtin_copysignf16, "hhh", "ncF")
-BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
-BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncF")
-BUILTIN(__builtin_fabs , "dd"  , "ncF")
-BUILTIN(__builtin_fabsf, "ff"  , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_copysignl, "LdLdLd", "ncFE")
+BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncFE")
+BUILTIN(__builtin_fabs , "dd"  , "ncFE")
+BUILTIN(__builtin_fabsf, "ff"  , "ncFE")
+BUILTIN(__builtin_fabsl, "LdLd", "ncFE")
 BUILTIN(__builtin_fabsf16, "hh"  , "ncF")
-BUILTIN(__builtin_fabsf128, "LLdLLd", "ncF")
+BUILTIN(__builtin_fabsf128, "LLdLLd", "ncFE")
 BUILTIN(__builtin_fmod , "ddd"  , "Fne")
 BUILTIN(__builtin_fmodf, "fff"  , "Fne")
 BUILTIN(__builtin_fmodf16, "hhh"  , "Fne")
@@ -140,16 +141,16 @@ BUILTIN(__builtin_

[clang] 27d8eed - [clang] Add time profile for constant evaluation

2022-10-21 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-21T23:24:44Z
New Revision: 27d8eedd5a3cd7fd644be4f06225ffa1ff04cccf

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

LOG: [clang] Add time profile for constant evaluation

Add time profiler for various constexpr evaluation events
so that slow event could be visible on the visualized flame chart.

Reviewed By: aaron.ballman

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

Added: 
clang/unittests/Support/CMakeLists.txt
clang/unittests/Support/TimeProfilerTest.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
clang/unittests/CMakeLists.txt

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3f952334c3d9a..79112e9420211 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -363,6 +363,8 @@ Non-comprehensive list of changes in this release
 - Clang now supports ``__has_constexpr_builtin`` function-like macro that
   evaluates to 1 if the builtin is supported and can be constant evaluated.
   It can be used to writing conditionally constexpr code that uses builtins.
+- The time profiler (using ``-ftime-trace`` option) now traces various constant
+  evaluation events.
 
 New Compiler Flags
 --

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6adc63d0f5f0d..4160aa6458c87 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -56,6 +56,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
@@ -660,6 +661,19 @@ namespace {
 CallStackFrame &Frame;
 const LValue *OldThis;
   };
+
+  // A shorthand time trace scope struct, prints source range, for example
+  // {"name":"EvaluateAsRValue","args":{"detail":""}}}
+  class ExprTimeTraceScope {
+  public:
+ExprTimeTraceScope(const Expr *E, const ASTContext &Ctx, StringRef Name)
+: TimeScope(Name, [E, &Ctx] {
+return E->getSourceRange().printToString(Ctx.getSourceManager());
+  }) {}
+
+  private:
+llvm::TimeTraceScope TimeScope;
+  };
 }
 
 static bool HandleDestruction(EvalInfo &Info, const Expr *E,
@@ -15105,6 +15119,7 @@ bool Expr::EvaluateAsRValue(EvalResult &Result, const 
ASTContext &Ctx,
 bool InConstantContext) const {
   assert(!isValueDependent() &&
  "Expression evaluator can't be called on a dependent expression.");
+  ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsRValue");
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
   Info.InConstantContext = InConstantContext;
   return ::EvaluateAsRValue(this, Result, Ctx, Info);
@@ -15114,6 +15129,7 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result, 
const ASTContext &Ctx,
   bool InConstantContext) const {
   assert(!isValueDependent() &&
  "Expression evaluator can't be called on a dependent expression.");
+  ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsBooleanCondition");
   EvalResult Scratch;
   return EvaluateAsRValue(Scratch, Ctx, InConstantContext) &&
  HandleConversionToBool(Scratch.Val, Result);
@@ -15124,6 +15140,7 @@ bool Expr::EvaluateAsInt(EvalResult &Result, const 
ASTContext &Ctx,
  bool InConstantContext) const {
   assert(!isValueDependent() &&
  "Expression evaluator can't be called on a dependent expression.");
+  ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsInt");
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
   Info.InConstantContext = InConstantContext;
   return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
@@ -15134,6 +15151,7 @@ bool Expr::EvaluateAsFixedPoint(EvalResult &Result, 
const ASTContext &Ctx,
 bool InConstantContext) const {
   assert(!isValueDependent() &&
  "Expression evaluator can't be called on a dependent expression.");
+  ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsFixedPoint");
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
   Info.InConstantContext = InConstantContext;
   return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
@@ -15148,6 +15166,7 @@ bool Expr::EvaluateAsFloat(APFloat &Result, const 
ASTContext &Ctx,
   if (!getType()->isRealFloatingType())
 return false;
 
+  ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsFloat");
   EvalResult ExprResult;
   if (!EvaluateAsRValue(ExprResult, Ctx, InConstantContext) ||
   !ExprResult.Val.isFloat() ||
@@ -15163,6 +15182,7 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const 
ASTContext &C

[clang] e5032d8 - [clang][unittest] Resolve ClangSupportTest link time errors

2022-10-23 Thread Evgeny Shulgin via cfe-commits

Author: John McIver
Date: 2022-10-23T09:54:39Z
New Revision: e5032d89e44a7fa5f2cc06925be28e87e3bdb9f0

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

LOG: [clang][unittest] Resolve ClangSupportTest link time errors

Resolves undefined references to vtable for clang::ASTConsumer,
PCHContainerOperations::PCHContainerOperations(), and
CodeGenOptions::CodeGenOptions().

Reviewed By: Izaron

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

Added: 


Modified: 
clang/unittests/Support/CMakeLists.txt

Removed: 




diff  --git a/clang/unittests/Support/CMakeLists.txt 
b/clang/unittests/Support/CMakeLists.txt
index 956b3a756150e..22be5ed18cc7a 100644
--- a/clang/unittests/Support/CMakeLists.txt
+++ b/clang/unittests/Support/CMakeLists.txt
@@ -8,5 +8,8 @@ add_clang_unittest(ClangSupportTests
 
 clang_target_link_libraries(ClangSupportTests
   PRIVATE
+  clangAST
+  clangBasic
   clangFrontend
+  clangSerialization
   )



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


[clang] 2bb50a5 - [clang] Fix time profile in "isIntegerConstantExpr"

2022-10-23 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-23T23:17:56Z
New Revision: 2bb50a55b0f5a88bd432ad2691060d82748b5bc0

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

LOG: [clang] Fix time profile in "isIntegerConstantExpr"

The time profiler in `Expr::isIntegerConstantExpr` used to
call `Loc->printToString`, it was inconsistent with other time
profiles in the file and caused segfaults if `Loc` was `nullptr`.

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

Reviewed By: dyung, jloser

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

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp
clang/unittests/Support/TimeProfilerTest.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4160aa6458c87..80541e077d4e5 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15905,9 +15905,7 @@ bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
   assert(!isValueDependent() &&
  "Expression evaluator can't be called on a dependent expression.");
 
-  llvm::TimeTraceScope TimeScope("isIntegerConstantExpr", [&] {
-return Loc->printToString(Ctx.getSourceManager());
-  });
+  ExprTimeTraceScope TimeScope(this, Ctx, "isIntegerConstantExpr");
 
   if (Ctx.getLangOpts().CPlusPlus11)
 return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc);

diff  --git a/clang/unittests/Support/TimeProfilerTest.cpp 
b/clang/unittests/Support/TimeProfilerTest.cpp
index a1b855493ab55..566cc6786461f 100644
--- a/clang/unittests/Support/TimeProfilerTest.cpp
+++ b/clang/unittests/Support/TimeProfilerTest.cpp
@@ -37,14 +37,14 @@ std::string teardownProfiler() {
 
 // Returns true if code compiles successfully.
 // We only parse AST here. This is enough for constexpr evaluation.
-bool compileFromString(StringRef Code) {
+bool compileFromString(StringRef Code, StringRef Standard, StringRef FileName) 
{
   CompilerInstance Compiler;
   Compiler.createDiagnostics();
 
   auto Invocation = std::make_shared();
   Invocation->getPreprocessorOpts().addRemappedFile(
-  "test.cc", MemoryBuffer::getMemBuffer(Code).release());
-  const char *Args[] = {"-std=c++20", "test.cc"};
+  FileName, MemoryBuffer::getMemBuffer(Code).release());
+  const char *Args[] = {Standard.data(), FileName.data()};
   CompilerInvocation::CreateFromArgs(*Invocation, Args,
  Compiler.getDiagnostics());
   Compiler.setInvocation(std::move(Invocation));
@@ -143,7 +143,7 @@ std::string buildTraceGraph(StringRef Json) {
 
 } // namespace
 
-TEST(TimeProfilerTest, ConstantEvaluation) {
+TEST(TimeProfilerTest, ConstantEvaluationCxx20) {
   constexpr StringRef Code = R"(
 void print(double value);
 
@@ -172,7 +172,7 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 
21}; // 25th line
 )";
 
   setupProfiler();
-  ASSERT_TRUE(compileFromString(Code));
+  ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc"));
   std::string Json = teardownProfiler();
   std::string TraceGraph = buildTraceGraph(Json);
   ASSERT_TRUE(TraceGraph == R"(
@@ -197,3 +197,25 @@ Frontend
   // NOTE: If this test is failing, run this test with
   // `llvm::errs() << TraceGraph;` and change the assert above.
 }
+
+TEST(TimeProfilerTest, ConstantEvaluationC99) {
+  constexpr StringRef Code = R"(
+struct {
+  short quantval[4]; // 3rd line
+} value;
+)";
+
+  setupProfiler();
+  ASSERT_TRUE(compileFromString(Code, "-std=c99", "test.c"));
+  std::string Json = teardownProfiler();
+  std::string TraceGraph = buildTraceGraph(Json);
+  ASSERT_TRUE(TraceGraph == R"(
+Frontend
+| isIntegerConstantExpr ()
+| EvaluateKnownConstIntCheckOverflow ()
+| PerformPendingInstantiations
+)");
+
+  // NOTE: If this test is failing, run this test with
+  // `llvm::errs() << TraceGraph;` and change the assert above.
+}



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


[clang] 5103836 - [Clang] Support label at end of compound statement

2022-09-17 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-09-17T15:34:56Z
New Revision: 510383626fe146e49ae5fa036638e543ce71e5d9

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

LOG: [Clang] Support label at end of compound statement

Implements paper P2324R2
https://wg21.link/p2324r2
https://github.com/cplusplus/papers/issues/1006

Reviewed By: cor3ntin

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

Added: 
clang/test/Parser/c2x-label.c
clang/test/Parser/cxx2b-label.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseStmt.cpp
clang/test/AST/ast-dump-stmt.c
clang/test/Parser/switch-recovery.cpp
clang/www/c_status.html
clang/www/cxx_status.html

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 240228a6d5e7..403d50b1c9d4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -269,6 +269,9 @@ C2x Feature Support
   so the [[maybe_unused]] attribute may be applied to a label to silence an
   ``-Wunused-label`` warning.
 
+- Implemented `WG14 N508 
`_,
+  so labels can placed everywhere inside a compound statement.
+
 C++ Language Changes in Clang
 -
 - Implemented DR692, DR1395 and DR1432. Use the ``-fclang-abi-compat=15`` 
option
@@ -313,6 +316,8 @@ C++20 Feature Support
 C++2b Feature Support
 ^
 
+- Support label at end of compound statement (`P2324 
`_).
+
 CUDA/HIP Language Changes in Clang
 --
 

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 84504b15764b..0293c2c03b52 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -295,8 +295,20 @@ def note_missing_selector_name : Note<
 def note_force_empty_selector_name : Note<
   "or insert whitespace before ':' to use %0 as parameter name "
   "and have an empty entry in the selector">;
-def err_label_end_of_compound_statement : Error<
-  "label at end of compound statement: expected statement">;
+def err_switch_label_end_of_compound_statement : Error<
+  "label at end of switch compound statement: expected statement">;
+def ext_c_label_end_of_compound_statement : ExtWarn<
+  "label at end of compound statement is a C2x extension">,
+   InGroup;
+def ext_cxx_label_end_of_compound_statement : ExtWarn<
+  "label at end of compound statement is a C++2b extension">,
+   InGroup;
+def warn_c2x_compat_label_end_of_compound_statement : Warning<
+  "label at end of compound statement is incompatible with C standards before 
C2x">,
+  InGroup, DefaultIgnore;
+def warn_cxx20_compat_label_end_of_compound_statement : Warning<
+  "label at end of compound statement is incompatible with C++ standards 
before C++2b">,
+  InGroup, DefaultIgnore;
 def err_address_of_label_outside_fn : Error<
   "use of address-of-label extension outside of a function body">;
 def err_asm_operand_wide_string_literal : Error<

diff  --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index d785c393fef9..1a3363604a33 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -679,9 +679,12 @@ StmtResult Parser::ParseSEHLeaveStatement() {
 
 /// ParseLabeledStatement - We have an identifier and a ':' after it.
 ///
+///   label:
+/// identifier ':'
+/// [GNU]   identifier ':' attributes[opt]
+///
 ///   labeled-statement:
-/// identifier ':' statement
-/// [GNU]   identifier ':' attributes[opt] statement
+/// label statement
 ///
 StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
  ParsedStmtContext StmtCtx) {
@@ -725,6 +728,20 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
 }
   }
 
+  // The label may have no statement following it
+  if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
+if (getLangOpts().CPlusPlus) {
+  Diag(Tok, getLangOpts().CPlusPlus2b
+? diag::warn_cxx20_compat_label_end_of_compound_statement
+: diag::ext_cxx_label_end_of_compound_statement);
+} else {
+  Diag(Tok, getLangOpts().C2x
+? diag::warn_c2x_compat_label_end_of_compound_statement
+: diag::ext_c_label_end_of_compound_statement);
+}
+SubStmt = Actions.ActOnNullStmt(ColonLoc);
+  }
+
   // If we've not parsed a statement yet, parse one now.
   if (!SubStmt.isInvalid() && !SubStmt.isUsable())
 SubStmt = ParseStatement(nullptr, StmtCtx);
@@ -873,8 +890,8 @@ StmtResult Parser::ParseCaseSta

[clang] 3285f9a - [Clang] Support case and default labels at end of compound statement

2022-09-21 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-09-21T19:37:22Z
New Revision: 3285f9a2392fd6bc79241b1e97b124079553e48d

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

LOG: [Clang] Support case and default labels at end of compound statement

Direct continuation of https://reviews.llvm.org/D133887

Reviewed By: #clang-language-wg, aaron.ballman

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

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseStmt.cpp
clang/test/AST/ast-dump-stmt.c
clang/test/C/C2x/n2508.c
clang/test/FixIt/fixit.c
clang/test/Parser/c2x-label.c
clang/test/Parser/cxx2b-label.cpp
clang/test/Parser/switch-recovery.cpp
clang/www/c_status.html

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 76d40c338d641..987aa050a0cef 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -295,8 +295,6 @@ def note_missing_selector_name : Note<
 def note_force_empty_selector_name : Note<
   "or insert whitespace before ':' to use %0 as parameter name "
   "and have an empty entry in the selector">;
-def err_switch_label_end_of_compound_statement : Error<
-  "label at end of switch compound statement: expected statement">;
 def ext_c_label_end_of_compound_statement : ExtWarn<
   "label at end of compound statement is a C2x extension">,
InGroup;

diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 72123993be6b2..e6144ae01c779 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2094,6 +2094,7 @@ class Parser : public CodeCompletionHandler {
   StmtResult ParseCompoundStatement(bool isStmtExpr,
 unsigned ScopeFlags);
   void ParseCompoundStatementLeadingPragmas();
+  void DiagnoseLabelAtEndOfCompoundStatement();
   bool ConsumeNullStmt(StmtVector &Stmts);
   StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
   bool ParseParenExprOrCondition(StmtResult *InitStmt,

diff  --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 1a3363604a33b..bc2710d7656df 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -730,15 +730,7 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes 
&Attrs,
 
   // The label may have no statement following it
   if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
-if (getLangOpts().CPlusPlus) {
-  Diag(Tok, getLangOpts().CPlusPlus2b
-? diag::warn_cxx20_compat_label_end_of_compound_statement
-: diag::ext_cxx_label_end_of_compound_statement);
-} else {
-  Diag(Tok, getLangOpts().C2x
-? diag::warn_c2x_compat_label_end_of_compound_statement
-: diag::ext_c_label_end_of_compound_statement);
-}
+DiagnoseLabelAtEndOfCompoundStatement();
 SubStmt = Actions.ActOnNullStmt(ColonLoc);
   }
 
@@ -882,18 +874,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext 
StmtCtx,
   // If we found a non-case statement, start by parsing it.
   StmtResult SubStmt;
 
-  if (Tok.isNot(tok::r_brace)) {
-SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
+  if (Tok.is(tok::r_brace)) {
+// "switch (X) { case 4: }", is valid and is treated as if label was
+// followed by a null statement.
+DiagnoseLabelAtEndOfCompoundStatement();
+SubStmt = Actions.ActOnNullStmt(ColonLoc);
   } else {
-// Nicely diagnose the common error "switch (X) { case 4: }", which is
-// not valid.  If ColonLoc doesn't point to a valid text location, there 
was
-// another parsing error, so avoid producing extra diagnostics.
-if (ColonLoc.isValid()) {
-  SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
-  Diag(AfterColonLoc, diag::err_switch_label_end_of_compound_statement)
-  << FixItHint::CreateInsertion(AfterColonLoc, " ;");
-}
-SubStmt = StmtError();
+SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
   }
 
   // Install the body into the most deeply-nested case.
@@ -939,15 +926,13 @@ StmtResult 
Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
 
   StmtResult SubStmt;
 
-  if (Tok.isNot(tok::r_brace)) {
-SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
+  if (Tok.is(tok::r_brace)) {
+// "switch (X) {... default: }", is valid and is treated as if label was
+// followed by a null statement.
+DiagnoseLabelAtEndOfCompoundStatement();
+SubStmt = Actions.ActOnNullStmt(ColonLoc);
   } else {
-// Diagnose the comm

[clang] 0edff6f - [Clang] Support constexpr builtin fmax

2022-10-07 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-07T20:27:17Z
New Revision: 0edff6faa26664772c41fed8d7759bba703f4987

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

LOG: [Clang] Support constexpr builtin fmax

Support constexpr version of __builtin_fmax and its variations.

Reviewed By: jcranmer-intel

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

Added: 
clang/test/Sema/constant-builtins-fmax.cpp

Modified: 
clang/docs/LanguageExtensions.rst
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index bbaf31cc9792e..0793523d91e55 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4660,6 +4660,7 @@ The following builtin intrinsics can be used in constant 
expressions:
 * ``__builtin_ffs``
 * ``__builtin_ffsl``
 * ``__builtin_ffsll``
+* ``__builtin_fmax``
 * ``__builtin_fpclassify``
 * ``__builtin_inf``
 * ``__builtin_isinf``

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 779bc1b73d39a..f100a4e19f8ad 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14023,6 +14023,24 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
 Result.copySign(RHS);
 return true;
   }
+
+  case Builtin::BI__builtin_fmax:
+  case Builtin::BI__builtin_fmaxf:
+  case Builtin::BI__builtin_fmaxl:
+  case Builtin::BI__builtin_fmaxf16:
+  case Builtin::BI__builtin_fmaxf128: {
+// TODO: Handle sNaN.
+APFloat RHS(0.);
+if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+!EvaluateFloat(E->getArg(1), RHS, Info))
+  return false;
+// When comparing zeroes, return +0.0 if one of the zeroes is positive.
+if (Result.isZero() && RHS.isZero() && Result.isNegative())
+  Result = RHS;
+else if (Result.isNaN() || RHS > Result)
+  Result = RHS;
+return true;
+  }
   }
 }
 

diff  --git a/clang/test/Sema/constant-builtins-fmax.cpp 
b/clang/test/Sema/constant-builtins-fmax.cpp
new file mode 100644
index 0..f44c63af94cf9
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-fmax.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+constexpr double NaN = __builtin_nan("");
+constexpr double Inf = __builtin_inf();
+constexpr double NegInf = -__builtin_inf();
+
+#define FMAX_TEST_SIMPLE(T, FUNC)   \
+static_assert(T(6.7890) == FUNC(T(1.2345), T(6.7890))); \
+static_assert(T(6.7890) == FUNC(T(6.7890), T(1.2345)));
+
+#define FMAX_TEST_NAN(T, FUNC)  \
+static_assert(Inf == FUNC(NaN, Inf));   \
+static_assert(NegInf == FUNC(NegInf, NaN)); \
+static_assert(0.0 == FUNC(NaN, 0.0));   \
+static_assert(-0.0 == FUNC(-0.0, NaN)); \
+static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
+static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
+static_assert(__builtin_isnan(FUNC(NaN, NaN)));
+
+#define FMAX_TEST_INF(T, FUNC)  \
+static_assert(Inf == FUNC(NegInf, Inf));\
+static_assert(Inf == FUNC(Inf, 0.0));   \
+static_assert(Inf == FUNC(-0.0, Inf));  \
+static_assert(Inf == FUNC(Inf, T(1.2345))); \
+static_assert(Inf == FUNC(T(-1.2345), Inf));
+
+#define FMAX_TEST_NEG_INF(T, FUNC) \
+static_assert(Inf == FUNC(Inf, NegInf));   \
+static_assert(0.0 == FUNC(NegInf, 0.0));   \
+static_assert(-0.0 == FUNC(-0.0, NegInf)); \
+static_assert(T(-1.2345) == FUNC(NegInf, T(-1.2345))); \
+static_assert(T(1.2345) == FUNC(T(1.2345), NegInf));
+
+#define FMAX_TEST_BOTH_ZERO(T, FUNC)   \
+static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0);  \
+static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == 1.0);  \
+static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == 1.0);  \
+static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);
+
+#define LIST_FMAX_TESTS(T, FUNC) \
+FMAX_TEST_SIMPLE(T, FUNC)\
+FMAX_TEST_NAN(T, FUNC)   \
+FMAX_TEST_INF(T, FUNC)   \
+FMAX_TEST_NEG_INF(T, FUNC)   \
+FMAX_TEST_BOTH_ZERO(T, FUNC)
+
+LIST_FMAX_TESTS(double, __builtin_fmax)
+LIST_FMAX_TESTS(float, __builtin_fmaxf)
+LIST_FMAX_TESTS((long double), __builtin_fmaxl)
+LIST_FMAX_TESTS(__fp16, __builtin_fmaxf16)
+#ifdef __FLOAT128__
+LIST_FMAX_TESTS(__float128, __builtin_fmaxf128)
+#endif



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


[clang] c585a44 - [Clang] Use C++17 in constant-builtins-fmax.cpp test

2022-10-07 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-07T21:31:38Z
New Revision: c585a44651f485c1a10fefdc6625ad998c05c61c

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

LOG: [Clang] Use C++17 in constant-builtins-fmax.cpp test

Add `-std=c++17` to the test so that buildbot won't fail

Reviewed By: efriedma

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

Added: 


Modified: 
clang/test/Sema/constant-builtins-fmax.cpp

Removed: 




diff  --git a/clang/test/Sema/constant-builtins-fmax.cpp 
b/clang/test/Sema/constant-builtins-fmax.cpp
index f44c63af94cf..c2fd97a4df63 100644
--- a/clang/test/Sema/constant-builtins-fmax.cpp
+++ b/clang/test/Sema/constant-builtins-fmax.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
 // expected-no-diagnostics
 
 constexpr double NaN = __builtin_nan("");



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


[clang-tools-extra] a8fbd11 - [clang-tidy] Ignore concepts in `misc-redundant-expression`

2022-10-08 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-08T10:37:16Z
New Revision: a8fbd1157debfe5872d4a34babef3aab75732aa7

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

LOG: [clang-tidy] Ignore concepts in `misc-redundant-expression`

The checker should ignore requirement expressions inside concept
definitions, because redundant expressions still make sense here

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

Reviewed By: njames93, aaron.ballman

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

Added: 

clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-cxx20.cpp

Modified: 
clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 5d30ad23a8531..e7c79331757a0 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -10,6 +10,7 @@
 #include "../utils/Matchers.h"
 #include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ExprConcepts.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
@@ -440,6 +441,8 @@ AST_MATCHER(Expr, isIntegerConstantExpr) {
   return Node.isIntegerConstantExpr(Finder->getASTContext());
 }
 
+AST_MATCHER(Expr, isRequiresExpr) { return isa(Node); }
+
 AST_MATCHER(BinaryOperator, operandsAreEquivalent) {
   return areEquivalentExpr(Node.getLHS(), Node.getRHS());
 }
@@ -858,6 +861,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
 
   const auto BannedIntegerLiteral =
   integerLiteral(expandedByMacro(KnownBannedMacroNames));
+  const auto BannedAncestor = expr(isRequiresExpr());
 
   // Binary with equivalent operands, like (X != 2 && X != 2).
   Finder->addMatcher(
@@ -873,7 +877,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
unless(hasType(realFloatingPointType())),
unless(hasEitherOperand(hasType(realFloatingPointType(,
unless(hasLHS(AnyLiteralExpr)),
-   unless(hasDescendant(BannedIntegerLiteral)))
+   unless(hasDescendant(BannedIntegerLiteral)),
+   unless(hasAncestor(BannedAncestor)))
.bind("binary")),
   this);
 
@@ -886,7 +891,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
  unless(isInTemplateInstantiation()),
  unless(binaryOperatorIsInMacro()),
  // TODO: if the banned macros are themselves duplicated
- unless(hasDescendant(BannedIntegerLiteral)))
+ unless(hasDescendant(BannedIntegerLiteral)),
+ unless(hasAncestor(BannedAncestor)))
   .bind("nested-duplicates"),
   this);
 
@@ -896,7 +902,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
conditionalOperator(expressionsAreEquivalent(),
// Filter noisy false positives.
unless(conditionalOperatorIsInMacro()),
-   unless(isInTemplateInstantiation()))
+   unless(isInTemplateInstantiation()),
+   unless(hasAncestor(BannedAncestor)))
.bind("cond")),
   this);
 
@@ -909,7 +916,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
 ">=", "&&", "||", "="),
parametersAreEquivalent(),
// Filter noisy false positives.
-   unless(isMacro()), unless(isInTemplateInstantiation()))
+   unless(isMacro()), unless(isInTemplateInstantiation()),
+   unless(hasAncestor(BannedAncestor)))
.bind("call")),
   this);
 
@@ -919,7 +927,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
   hasAnyOverloadedOperatorName("|", "&", "||", "&&", "^"),
   nestedParametersAreEquivalent(), argumentCountIs(2),
   // Filter noisy false positives.
-  unless(isMacro()), unless(isInTemplateInstantiation()))
+  unless(isMacro()), unless(isInTemplateInstantiation()),
+  unless(hasAncestor(BannedAncestor)))
   .bind("nested-duplicates"),
   this);
 
@@ -936,7 +945,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
bina

[clang] ec32386 - [Clang] Support constexpr builtin fmin

2022-10-10 Thread Evgeny Shulgin via cfe-commits

Author: Evgeny Shulgin
Date: 2022-10-10T16:06:23Z
New Revision: ec32386404409b65d21fdf916110c08912335926

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

LOG: [Clang] Support constexpr builtin fmin

Support constexpr version of __builtin_fmin and its variations.

Reviewed By: jcranmer-intel

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

Added: 
clang/test/Sema/constant-builtins-fmin.cpp

Modified: 
clang/docs/LanguageExtensions.rst
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 0793523d91e55..f680b1f1d2ad7 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -4661,6 +4661,7 @@ The following builtin intrinsics can be used in constant 
expressions:
 * ``__builtin_ffsl``
 * ``__builtin_ffsll``
 * ``__builtin_fmax``
+* ``__builtin_fmin``
 * ``__builtin_fpclassify``
 * ``__builtin_inf``
 * ``__builtin_isinf``

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f100a4e19f8ad..64c50c8b82e5a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14041,6 +14041,24 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr 
*E) {
   Result = RHS;
 return true;
   }
+
+  case Builtin::BI__builtin_fmin:
+  case Builtin::BI__builtin_fminf:
+  case Builtin::BI__builtin_fminl:
+  case Builtin::BI__builtin_fminf16:
+  case Builtin::BI__builtin_fminf128: {
+// TODO: Handle sNaN.
+APFloat RHS(0.);
+if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+!EvaluateFloat(E->getArg(1), RHS, Info))
+  return false;
+// When comparing zeroes, return -0.0 if one of the zeroes is negative.
+if (Result.isZero() && RHS.isZero() && RHS.isNegative())
+  Result = RHS;
+else if (Result.isNaN() || RHS < Result)
+  Result = RHS;
+return true;
+  }
   }
 }
 

diff  --git a/clang/test/Sema/constant-builtins-fmin.cpp 
b/clang/test/Sema/constant-builtins-fmin.cpp
new file mode 100644
index 0..bf3e81e21e617
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-fmin.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+constexpr double NaN = __builtin_nan("");
+constexpr double Inf = __builtin_inf();
+constexpr double NegInf = -__builtin_inf();
+
+#define FMIN_TEST_SIMPLE(T, FUNC)   \
+static_assert(T(1.2345) == FUNC(T(1.2345), T(6.7890))); \
+static_assert(T(1.2345) == FUNC(T(6.7890), T(1.2345)));
+
+#define FMIN_TEST_NAN(T, FUNC)  \
+static_assert(Inf == FUNC(NaN, Inf));   \
+static_assert(NegInf == FUNC(NegInf, NaN)); \
+static_assert(0.0 == FUNC(NaN, 0.0));   \
+static_assert(-0.0 == FUNC(-0.0, NaN)); \
+static_assert(T(-1.2345) == FUNC(NaN, T(-1.2345))); \
+static_assert(T(1.2345) == FUNC(T(1.2345), NaN));   \
+static_assert(__builtin_isnan(FUNC(NaN, NaN)));
+
+#define FMIN_TEST_INF(T, FUNC)\
+static_assert(NegInf == FUNC(NegInf, Inf));   \
+static_assert(0.0 == FUNC(Inf, 0.0)); \
+static_assert(-0.0 == FUNC(-0.0, Inf));   \
+static_assert(T(1.2345) == FUNC(Inf, T(1.2345))); \
+static_assert(T(-1.2345) == FUNC(T(-1.2345), Inf));
+
+#define FMIN_TEST_NEG_INF(T, FUNC) \
+static_assert(NegInf == FUNC(Inf, NegInf));\
+static_assert(NegInf == FUNC(NegInf, 0.0));\
+static_assert(NegInf == FUNC(-0.0, NegInf));   \
+static_assert(NegInf == FUNC(NegInf, T(-1.2345))); \
+static_assert(NegInf == FUNC(T(1.2345), NegInf));
+
+#define FMIN_TEST_BOTH_ZERO(T, FUNC) \
+static_assert(__builtin_copysign(1.0, FUNC(0.0, 0.0)) == 1.0);   \
+static_assert(__builtin_copysign(1.0, FUNC(-0.0, 0.0)) == -1.0); \
+static_assert(__builtin_copysign(1.0, FUNC(0.0, -0.0)) == -1.0); \
+static_assert(__builtin_copysign(1.0, FUNC(-0.0, -0.0)) == -1.0);
+
+#define LIST_FMIN_TESTS(T, FUNC) \
+FMIN_TEST_SIMPLE(T, FUNC)\
+FMIN_TEST_NAN(T, FUNC)   \
+FMIN_TEST_INF(T, FUNC)   \
+FMIN_TEST_NEG_INF(T, FUNC)   \
+FMIN_TEST_BOTH_ZERO(T, FUNC)
+
+LIST_FMIN_TESTS(double, __builtin_fmin)
+LIST_FMIN_TESTS(float, __builtin_fminf)
+LIST_FMIN_TESTS((long double), __builtin_fminl)
+LIST_FMIN_TESTS(__fp16, __builtin_fminf16)
+#ifdef __FLOAT128__
+LIST_FMIN_TESTS(__float128, __builtin_fminf128)
+#endif



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