[clang] [PAC] Re-sign a pointer to a noexcept member function when it is converted to a pointer to a member function without noexcept (PR #109056)

2024-09-19 Thread Akira Hatanaka via cfe-commits


@@ -2419,8 +2419,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
 return Visit(const_cast(E));
 
   case CK_NoOp: {
-return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
-  : Visit(const_cast(E));
+if (CE->changesVolatileQualification())
+  return EmitLoadOfLValue(CE);
+auto V = Visit(const_cast(E));
+if (CGF.CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers &&
+CE->getType()->isMemberFunctionPointerType())
+  V = CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, V);
+return V;

ahatanak wrote:

I don't think there's a `CastKind` we can use in 
`clang/AST/OperationKinds.def`. We'll have to define a new one if we are going 
to stop using `NoOp`.

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


[clang] [PAC] Re-sign a pointer to a noexcept member function when it is converted to a pointer to a member function without noexcept (PR #109056)

2024-09-18 Thread Akira Hatanaka via cfe-commits


@@ -2419,8 +2419,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
 return Visit(const_cast(E));
 
   case CK_NoOp: {
-return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
-  : Visit(const_cast(E));
+if (CE->changesVolatileQualification())
+  return EmitLoadOfLValue(CE);
+auto V = Visit(const_cast(E));
+if (CGF.CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers &&
+CE->getType()->isMemberFunctionPointerType())
+  V = CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, V);
+return V;

ahatanak wrote:

Depending on the kind of casts in the source code, `CStyleCastExpr` or 
`CXXReinterpretCastExpr` (or possibly another cast kind) is used when casting 
to a completely different function pointer type.

But those are explicit casts. I'm not sure there's another cast operation other 
than `CK_NoOp` in `clang/AST/OperationKinds.def` that we can use for that 
purpose.

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


[clang] [PAC] Re-sign a pointer to a noexcept member function when it is converted to a pointer to a member function without noexcept (PR #109056)

2024-09-18 Thread Akira Hatanaka via cfe-commits


@@ -2419,8 +2419,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
 return Visit(const_cast(E));
 
   case CK_NoOp: {
-return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
-  : Visit(const_cast(E));
+if (CE->changesVolatileQualification())
+  return EmitLoadOfLValue(CE);
+auto V = Visit(const_cast(E));
+if (CGF.CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers &&
+CE->getType()->isMemberFunctionPointerType())
+  V = CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, V);
+return V;

ahatanak wrote:

Sema does use `CK_NoOp` for those, but we don't need to re-sign function 
pointers because the presence of `noexcept` on a function type doesn't change 
the discriminator. The function that encodes the function type 
(`encodeTypeForFunctionPointerAuth`) encodes the parameter and return types, 
but ignores `noexcept`.

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


[clang] [PAC] Re-sign a pointer to a noexcept member function when it is converted to a pointer to a member function without noexcept (PR #109056)

2024-09-17 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/109056

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

>From eede4b2c2916a3016643fb56f87f7601dfaff69b Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Mon, 16 Sep 2024 17:12:13 -0700
Subject: [PATCH] [PAC] Re-sign a pointer to a noexcept member function when it
 is converted to a pointer to a member function without noexcept

Fixes https://github.com/llvm/llvm-project/issues/106487.
---
 clang/lib/CodeGen/CGExprScalar.cpp|   9 +-
 clang/lib/CodeGen/ItaniumCXXABI.cpp   |  28 -
 .../ptrauth-member-function-pointer.cpp   | 109 +-
 3 files changed, 136 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 82caf65ac68d6b..76e2f047e84ae4 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2419,8 +2419,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
 return Visit(const_cast(E));
 
   case CK_NoOp: {
-return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
-  : Visit(const_cast(E));
+if (CE->changesVolatileQualification())
+  return EmitLoadOfLValue(CE);
+auto V = Visit(const_cast(E));
+if (CGF.CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers &&
+CE->getType()->isMemberFunctionPointerType())
+  V = CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, V);
+return V;
   }
 
   case CK_BaseToDerived: {
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp 
b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index dcc35d5689831e..085ed84b5108b4 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -924,17 +924,20 @@ 
ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
   if (isa(src))
 return EmitMemberPointerConversion(E, cast(src));
 
+  QualType DstType = E->getType(), SrcType = E->getSubExpr()->getType();
+
   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
  E->getCastKind() == CK_BaseToDerivedMemberPointer ||
- E->getCastKind() == CK_ReinterpretMemberPointer);
+ E->getCastKind() == CK_ReinterpretMemberPointer ||
+ (E->getCastKind() == CK_NoOp &&
+  getContext().hasSameFunctionTypeIgnoringExceptionSpec(
+  DstType->getPointeeType(), SrcType->getPointeeType(;
 
   CGBuilderTy &Builder = CGF.Builder;
-  QualType DstType = E->getType();
 
   if (DstType->isMemberFunctionPointerType()) {
 if (const auto &NewAuthInfo =
 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
-  QualType SrcType = E->getSubExpr()->getType();
   assert(SrcType->isMemberFunctionPointerType());
   const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
   llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0, "memptr.ptr");
@@ -971,6 +974,11 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction 
&CGF,
 }
   }
 
+  // Conversion from a pointer to a noexcept member function to a pointer to a
+  // member function without noexcept doesn't require any additional 
processing.
+  if (E->getCastKind() == CK_NoOp)
+return src;
+
   // Under Itanium, reinterprets don't require any additional processing.
   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
 
@@ -1045,16 +1053,24 @@ pointerAuthResignMemberFunctionPointer(llvm::Constant 
*Src, QualType DestType,
 llvm::Constant *
 ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
llvm::Constant *src) {
+  QualType DstType = E->getType(), SrcType = E->getSubExpr()->getType();
+
   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
  E->getCastKind() == CK_BaseToDerivedMemberPointer ||
- E->getCastKind() == CK_ReinterpretMemberPointer);
-
-  QualType DstType = E->getType();
+ E->getCastKind() == CK_ReinterpretMemberPointer ||
+ (E->getCastKind() == CK_NoOp &&
+  getContext().hasSameFunctionTypeIgnoringExceptionSpec(
+  DstType->getPointeeType(), SrcType->getPointeeType(;
 
   if (DstType->isMemberFunctionPointerType())
 src = pointerAuthResignMemberFunctionPointer(
 src, DstType, E->getSubExpr()->getType(), CGM);
 
+  // Conversion from a pointer to a noexcept member function to a pointer to a
+  // member function without noexcept doesn't require any additional 
processing.
+  if (E->getCastKind() == CK_NoOp)
+return src;
+
   // Under Itanium, reinterprets don't require any additional processing.
   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
 
diff --git a/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp 
b/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp
index 0a9ac3fa510f56..3408e7e18c3adc 100644
--- a/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp
+++ b/clang/test/Code

[clang] [Clang][Sema] Fix crash when type used in return statement contains errors (PR #79788)

2024-08-20 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

I think this change can confuse users in some cases.

```
class Error {
public:
  Error() = default;
  Error(Error &&);
  Error &operator=(Error &&);
  explicit operator bool() const;
};

Error getError();

Error foo() {
  if (Error e = getError(1)) {
return e;
  }
  return Error();
}
```

When the code above is compiled, clang complains that the implicitly-deleted 
copy constructor of 'Error' is called. This makes users wonder why `return e` 
isn't eligible for copy elision.

I wonder whether it would be better to check that `VD`'s type is incomplete 
rather than calling `containsErrors`.

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-14 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

RFC for `__ptrauth`: https://discourse.llvm.org/t/rfc-ptrauth-qualifier/80710

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-09 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

I'll try to come up with an RFC for the qualifier today.

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-09 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

@rjmccall sent an RFC for upstreaming pointer authentication work to llvm-dev 
in 2019, which mentions the `__ptrauth` qualifier. 
https://discourse.llvm.org/t/rfc-pointer-authentication-for-arm64e/53433

I don't think we sent an RFC for adding support for the `__ptrauth` qualifier.

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


[clang] Run test with triple arm64-apple-ios (PR #102343)

2024-08-07 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-07 Thread Akira Hatanaka via cfe-commits


@@ -104,6 +104,7 @@ FEATURE(thread_sanitizer, 
LangOpts.Sanitize.has(SanitizerKind::Thread))
 FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
 FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
 FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
+FEATURE(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics)

ahatanak wrote:

Yes, that's right. We currently don't have a separate flag or predicate for 
ptrauth qualifier.

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


[clang] Run test with triple arm64-apple-ios (PR #102343)

2024-08-07 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/102343

None

>From 2cc9159dd6592579d8cf91d37cd6f1826d402f53 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 7 Aug 2024 09:05:11 -0700
Subject: [PATCH] Run test with triple arm64-apple-ios

---
 clang/test/CodeGenCXX/mangle-fail.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/test/CodeGenCXX/mangle-fail.cpp 
b/clang/test/CodeGenCXX/mangle-fail.cpp
index f3b50cfb54dbd..a2fd16be4df1e 100644
--- a/clang/test/CodeGenCXX/mangle-fail.cpp
+++ b/clang/test/CodeGenCXX/mangle-fail.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=1
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=2
+// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple arm64-apple-ios 
-fptrauth-intrinsics -verify %s -DN=3
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple aarch64-linux-gnu 
-fptrauth-intrinsics -verify %s -DN=3
 
 struct A { int a; };

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-06 Thread Akira Hatanaka via cfe-commits


@@ -104,6 +104,7 @@ FEATURE(thread_sanitizer, 
LangOpts.Sanitize.has(SanitizerKind::Thread))
 FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
 FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
 FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
+FEATURE(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics)

ahatanak wrote:

Why is it strange? Because it uses `LangOpts.PointerAuthIntrinsics` as the 
predicate?

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


[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

2024-08-01 Thread Akira Hatanaka via cfe-commits

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


[clang] [lld] [llvm] [LTO] enable `ObjCARCContractPass` only on optimized build (PR #101114)

2024-07-30 Thread Akira Hatanaka via cfe-commits


@@ -588,12 +588,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager 
&CodeGenPasses,
   // this also adds codegenerator level optimization passes.
   CodeGenFileType CGFT = getCodeGenFileType(Action);
 
-  // Add ObjC ARC final-cleanup optimizations. This is done as part of the

ahatanak wrote:

The intrinsic calls are needed to prevent ARC optimizer from moving releases to 
an earlier point that can cause objects to be deallocated prematurely. clang 
doesn't emit the intrinsic calls if `OptimizationLevel` is zero.

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


[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)

2024-07-23 Thread Akira Hatanaka via cfe-commits


@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=1
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=2
+// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=3

ahatanak wrote:

The test case is guarded by `#elif N == 3`, so `aarch64-registered-target` 
isn't needed.

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


[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)

2024-07-23 Thread Akira Hatanaka via cfe-commits


@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=1
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=2
+// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple 
%itanium_abi_triple -verify %s -DN=3

ahatanak wrote:

Adding `-triple aarch64-linux-gnu -fptrauth-intrinsics` fixed the test.

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


[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)

2024-07-23 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/100204

>From 4cbbf9ee2c5afaa3818c10ab6f2645353da94a8c Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 23 Jul 2024 11:55:57 -0700
Subject: [PATCH 1/2] [PAC] Define __builtin_ptrauth_type_discriminator

The builtin computes the discriminator for a type, which can be used to
sign/authenticate function pointers and member function pointers.

If the type passed to the builtin is a C++ member function pointer type,
the result is the discriminator used to signed member function pointers
of that type. If the type is a function, function pointer, or function
reference type, the result is the discriminator used to sign functions
of that type. It is ill-formed to use this builtin with any other type.

A call to this function is an integer constant expression.

Co-Authored-By: John McCall rjmcc...@apple.com
---
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/include/clang/Parse/Parser.h|  2 +
 clang/include/clang/Sema/Sema.h   |  2 +
 clang/lib/AST/ExprConstant.cpp|  6 ++
 clang/lib/AST/ItaniumMangle.cpp   |  8 +++
 clang/lib/Headers/ptrauth.h   | 19 ++
 clang/lib/Parse/ParseExpr.cpp | 23 +++
 clang/lib/Sema/SemaChecking.cpp   | 10 ++-
 clang/lib/Sema/SemaExpr.cpp   | 19 ++
 clang/test/AST/ast-dump-ptrauth-json.cpp  |  5 ++
 clang/test/CodeGenCXX/mangle-fail.cpp | 14 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 ++
 .../SemaCXX/ptrauth-type-discriminator.cpp| 64 +++
 14 files changed, 179 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-ptrauth-json.cpp
 create mode 100644 clang/test/SemaCXX/ptrauth-type-discriminator.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 00affee1ea67f..045c493e88c31 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -942,6 +942,9 @@ def warn_ptrauth_auth_null_pointer :
   InGroup;
 def err_ptrauth_string_not_literal : Error<
   "argument must be a string literal%select{| of char type}0">;
+def err_ptrauth_type_disc_undiscriminated : Error<
+  "cannot pass undiscriminated type %0 to "
+  "'__builtin_ptrauth_type_discriminator'">;
 
 def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
   Note<"cannot take an address of a virtual member function if its return or "
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 7f4912b9bcd96..8c54661e65cf4 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -596,6 +596,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX)
 KEYWORD(__private_extern__  , KEYALL)
 KEYWORD(__module_private__  , KEYALL)
 
+UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, 
PtrAuthTypeDiscriminator, KEYALL)
+
 // Extension that will be enabled for Microsoft, Borland and PS4, but can be
 // disabled via '-fno-declspec'.
 KEYWORD(__declspec  , 0)
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 613bab9120dfc..35bb1a19d40f0 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3890,6 +3890,8 @@ class Parser : public CodeCompletionHandler {
   ExprResult ParseArrayTypeTrait();
   ExprResult ParseExpressionTrait();
 
+  ExprResult ParseBuiltinPtrauthTypeDiscriminator();
+
   
//======//
   // Preprocessor code-completion pass-through
   void CodeCompleteDirective(bool InConditional) override;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d638d31e050dc..7bfdaaae45a93 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3456,6 +3456,8 @@ class Sema final : public SemaBase {
 TemplateIdAnnotation *TemplateId,
 bool IsMemberSpecialization);
 
+  bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range);
+
   bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key);
 
   /// Diagnose function specifiers on a declaration of an identifier that
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fcb382474ea62..03a606102a77e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14054,6 +14054,12 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
  E);
   }
 
+  case UETT_PtrAuthTypeDiscriminator: {
+if (E->getArgumentType()->isDependentType())
+  return false;
+return Success(
+Info.Ctx.getPointerAuthTypeDiscriminator(E->getArgumentType()), E);
+

[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)

2024-07-23 Thread Akira Hatanaka via cfe-commits


@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla -fsyntax-only 
-verify -fptrauth-intrinsics %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++17 -Wno-vla -fsyntax-only 
-verify -fptrauth-intrinsics %s
+
+// RUN: not %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla 
-fsyntax-only %s 2>&1 | FileCheck %s
+// CHECK: this target does not support pointer authentication
+
+struct S {
+  virtual int foo();
+};
+
+template 
+constexpr unsigned dependentOperandDisc() {
+  return __builtin_ptrauth_type_discriminator(T);
+}
+
+void test_builtin_ptrauth_type_discriminator(unsigned s) {
+  typedef int (S::*MemFnTy)();
+  MemFnTy memFnPtr;
+  int (S::*memFnPtr2)();
+  constexpr unsigned d0 = __builtin_ptrauth_type_discriminator(MemFnTy);
+  static_assert(d0 == __builtin_ptrauth_string_discriminator("_ZTSM1SFivE"));
+  static_assert(d0 == 60844);
+  static_assert(__builtin_ptrauth_type_discriminator(int (S::*)()) == d0);
+  static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr)) == 
d0);
+  static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr2)) == 
d0);
+  static_assert(__builtin_ptrauth_type_discriminator(decltype(&S::foo)) == d0);
+  static_assert(dependentOperandDisc() == d0);
+
+  constexpr unsigned d1 = __builtin_ptrauth_type_discriminator(void 
(S::*)(int));
+  static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFviE") == d1);
+  static_assert(d1 == 39121);
+
+  constexpr unsigned d2 = __builtin_ptrauth_type_discriminator(void 
(S::*)(float));
+  static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFvfE") == d2);
+  static_assert(d2 == 52453);
+
+  constexpr unsigned d3 = __builtin_ptrauth_type_discriminator(int (*())[s]);
+  static_assert(__builtin_ptrauth_string_discriminator("FPE") == d3);
+  static_assert(d3 == 34128);
+
+  int f4(float);
+  constexpr unsigned d4 = __builtin_ptrauth_type_discriminator(decltype(f4));
+  static_assert(__builtin_ptrauth_type_discriminator(int (*)(float)) == d4);
+  static_assert(__builtin_ptrauth_string_discriminator("FifE") == d4);
+  static_assert(d4 == 48468);
+
+  int f5(int);
+  constexpr unsigned d5 = __builtin_ptrauth_type_discriminator(decltype(f5));
+  static_assert(__builtin_ptrauth_type_discriminator(int (*)(int)) == d5);
+  static_assert(__builtin_ptrauth_type_discriminator(short (*)(short)) == d5);
+  static_assert(__builtin_ptrauth_type_discriminator(char (*)(char)) == d5);
+  static_assert(__builtin_ptrauth_type_discriminator(long (*)(long)) == d5);
+  static_assert(__builtin_ptrauth_type_discriminator(unsigned int (*)(unsigned 
int)) == d5);
+  static_assert(__builtin_ptrauth_type_discriminator(int (&)(int)) == d5);
+  static_assert(__builtin_ptrauth_string_discriminator("FiiE") == d5);
+  static_assert(d5 == 2981);
+
+  int t;
+  int vmarray[s];
+  (void)__builtin_ptrauth_type_discriminator(t); // expected-error {{unknown 
type name 't'}}
+  (void)__builtin_ptrauth_type_discriminator(&t); // expected-error {{expected 
a type}}
+  (void)__builtin_ptrauth_type_discriminator(decltype(vmarray)); // 
expected-error {{cannot pass undiscriminated type 'decltype(vmarray)' (aka 
'int[s]')}}
+  (void)__builtin_ptrauth_type_discriminator(int *); // expected-error 
{{cannot pass undiscriminated type 'int *' to 
'__builtin_ptrauth_type_discriminator'}}

ahatanak wrote:

Do you mean a test case in which the discriminators for the two function types 
(one argument versus two arguments) are different?

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


[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)

2024-07-23 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/100204

The builtin computes the discriminator for a type, which can be used to 
sign/authenticate function pointers and member function pointers.

If the type passed to the builtin is a C++ member function pointer type, the 
result is the discriminator used to signed member function pointers of that 
type. If the type is a function, function pointer, or function reference type, 
the result is the discriminator used to sign functions of that type. It is 
ill-formed to use this builtin with any other type.

A call to this function is an integer constant expression.

Co-Authored-By: John McCall rjmcc...@apple.com

>From 4cbbf9ee2c5afaa3818c10ab6f2645353da94a8c Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 23 Jul 2024 11:55:57 -0700
Subject: [PATCH] [PAC] Define __builtin_ptrauth_type_discriminator

The builtin computes the discriminator for a type, which can be used to
sign/authenticate function pointers and member function pointers.

If the type passed to the builtin is a C++ member function pointer type,
the result is the discriminator used to signed member function pointers
of that type. If the type is a function, function pointer, or function
reference type, the result is the discriminator used to sign functions
of that type. It is ill-formed to use this builtin with any other type.

A call to this function is an integer constant expression.

Co-Authored-By: John McCall rjmcc...@apple.com
---
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/include/clang/Basic/TokenKinds.def  |  2 +
 clang/include/clang/Parse/Parser.h|  2 +
 clang/include/clang/Sema/Sema.h   |  2 +
 clang/lib/AST/ExprConstant.cpp|  6 ++
 clang/lib/AST/ItaniumMangle.cpp   |  8 +++
 clang/lib/Headers/ptrauth.h   | 19 ++
 clang/lib/Parse/ParseExpr.cpp | 23 +++
 clang/lib/Sema/SemaChecking.cpp   | 10 ++-
 clang/lib/Sema/SemaExpr.cpp   | 19 ++
 clang/test/AST/ast-dump-ptrauth-json.cpp  |  5 ++
 clang/test/CodeGenCXX/mangle-fail.cpp | 14 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 ++
 .../SemaCXX/ptrauth-type-discriminator.cpp| 64 +++
 14 files changed, 179 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-ptrauth-json.cpp
 create mode 100644 clang/test/SemaCXX/ptrauth-type-discriminator.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 00affee1ea67f..045c493e88c31 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -942,6 +942,9 @@ def warn_ptrauth_auth_null_pointer :
   InGroup;
 def err_ptrauth_string_not_literal : Error<
   "argument must be a string literal%select{| of char type}0">;
+def err_ptrauth_type_disc_undiscriminated : Error<
+  "cannot pass undiscriminated type %0 to "
+  "'__builtin_ptrauth_type_discriminator'">;
 
 def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
   Note<"cannot take an address of a virtual member function if its return or "
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 7f4912b9bcd96..8c54661e65cf4 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -596,6 +596,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX)
 KEYWORD(__private_extern__  , KEYALL)
 KEYWORD(__module_private__  , KEYALL)
 
+UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, 
PtrAuthTypeDiscriminator, KEYALL)
+
 // Extension that will be enabled for Microsoft, Borland and PS4, but can be
 // disabled via '-fno-declspec'.
 KEYWORD(__declspec  , 0)
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 613bab9120dfc..35bb1a19d40f0 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3890,6 +3890,8 @@ class Parser : public CodeCompletionHandler {
   ExprResult ParseArrayTypeTrait();
   ExprResult ParseExpressionTrait();
 
+  ExprResult ParseBuiltinPtrauthTypeDiscriminator();
+
   
//======//
   // Preprocessor code-completion pass-through
   void CodeCompleteDirective(bool InConditional) override;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d638d31e050dc..7bfdaaae45a93 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3456,6 +3456,8 @@ class Sema final : public SemaBase {
 TemplateIdAnnotation *TemplateId,
 bool IsMemberSpecialization);
 
+  bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range);
+
   bool checkConstantPointerAuthKey(Expr *keyExpr, u

[clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)

2024-07-22 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

Do we have to fix this just to appease gcc 9.2? It looks like newer versions of 
gcc (after 9.3) don't emit the warning.

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


[clang] [ASTContext] Add a break to nested switch in `encodeTypeForFunctionPointerAuth` (PR #99763)

2024-07-22 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

Should we use unreachable If it's not possible to suppress the warning from gcc?

https://llvm.org/docs/CodingStandards.html#don-t-use-default-labels-in-fully-covered-switches-over-enumerations

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


[clang] [PAC] Fix a crash when signing a pointer to a function with an incomplete enum parameter (PR #99595)

2024-07-19 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Authenticate function pointers in UBSan type checks (PR #99590)

2024-07-19 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Fix a crash when signing a pointer to a function with an incomplete enum parameter (PR #99595)

2024-07-18 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/99595

Use type int as the underlying type when the enum type is incomplete.

>From 14612f84704edbcc3b3bcb20d6e114890e1c3998 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 18 Jul 2024 17:59:46 -0700
Subject: [PATCH] [PAC] Fix a crash when signing a pointer to a function with
 an incomplete enum parameter

Use type int as the underlying type when the enum type is incomplete.
---
 clang/lib/AST/ASTContext.cpp | 6 --
 clang/test/CodeGen/ptrauth-function-type-discriminator.c | 7 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a8e599f7ebe04..9eb529c29bebb 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3222,14 +3222,16 @@ static void encodeTypeForFunctionPointerAuth(const 
ASTContext &Ctx,
 OS << "";
 return;
 
-  case Type::Enum:
+  case Type::Enum: {
 // C11 6.7.2.2p4:
 //   Each enumerated type shall be compatible with char, a signed integer
 //   type, or an unsigned integer type.
 //
 // So we have to treat enum types as integers.
+QualType UnderlyingType = cast(T)->getDecl()->getIntegerType();
 return encodeTypeForFunctionPointerAuth(
-Ctx, OS, cast(T)->getDecl()->getIntegerType());
+Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType);
+  }
 
   case Type::FunctionNoProto:
   case Type::FunctionProto: {
diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c 
b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
index 5dea48fe5915b..54634ed528fb3 100644
--- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c
+++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
@@ -19,6 +19,13 @@ void (*test_constant_null)(int) = 0;
 // CHECK: @test_constant_cast = global ptr ptrauth (ptr @f, i32 0, i64 2712)
 void (*test_constant_cast)(int) = (void (*)(int))f;
 
+#ifndef __cplusplus
+// CHECKC: @enum_func_ptr = global ptr ptrauth (ptr @enum_func, i32 0, i64 
2712)
+enum Enum0;
+void enum_func(enum Enum0);
+void (*enum_func_ptr)(enum Enum0) = enum_func;
+#endif
+
 // CHECK: @test_opaque = global ptr ptrauth (ptr @f, i32 0)
 void *test_opaque =
 #ifdef __cplusplus

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


[clang] [PAC] Authenticate function pointers in UBSan type checks (PR #99590)

2024-07-18 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/99590

The function pointer needs to be authenticated before doing the type checks.

>From c44fbc480f8632a178633637010ab6953ed3e50d Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 18 Jul 2024 16:54:09 -0700
Subject: [PATCH] [PAC] Authenticate function pointers in UBSan type checks

The function pointer needs to be authenticated before doing the type
checks.
---
 clang/lib/CodeGen/Address.h   | 4 +++-
 clang/lib/CodeGen/CGExpr.cpp  | 9 +
 clang/lib/CodeGen/CGPointerAuth.cpp   | 4 
 clang/test/CodeGen/ubsan-function.cpp | 4 
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 1c4d2e103b5e7..a18c7169af1eb 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -249,7 +249,9 @@ class Address {
   /// Return the pointer contained in this class after authenticating it and
   /// adding offset to it if necessary.
   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-return getBasePointer();
+if (!isSigned())
+  return getBasePointer();
+return emitRawPointerSlow(CGF);
   }
 
   /// Return address with different pointer, but same element type and
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c5341e4b53651..aa53f96358044 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5837,6 +5837,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, 
const CGCallee &OrigCallee
   CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true);
 
   llvm::Value *CalleePtr = Callee.getFunctionPointer();
+  if (CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
+// Use raw pointer since we are using the callee pointer as data here.
+Address Addr =
+Address(CalleePtr, CalleePtr->getType(),
+CharUnits::fromQuantity(
+CalleePtr->getPointerAlignment(CGM.getDataLayout())),
+Callee.getPointerAuthInfo(), nullptr);
+CalleePtr = Addr.emitRawPointer(*this);
+  }
 
   // On 32-bit Arm, the low bit of a function pointer indicates whether
   // it's using the Arm or Thumb instruction set. The actual first
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp 
b/clang/lib/CodeGen/CGPointerAuth.cpp
index 7fe62c0788742..72aed9f24d595 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -566,6 +566,10 @@ Address Address::getResignedAddress(const 
CGPointerAuthInfo &NewInfo,
  /*Offset=*/nullptr, isKnownNonNull());
 }
 
+llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
+  return CGF.getAsNaturalPointerTo(*this, QualType());
+}
+
 llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
   assert(isSimple());
   return emitResignedPointer(getType(), CGF);
diff --git a/clang/test/CodeGen/ubsan-function.cpp 
b/clang/test/CodeGen/ubsan-function.cpp
index bc37a61c98ee3..8478f05a10b78 100644
--- a/clang/test/CodeGen/ubsan-function.cpp
+++ b/clang/test/CodeGen/ubsan-function.cpp
@@ -4,6 +4,8 @@
 // RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s 
-fsanitize=function -fno-sanitize-recover=all | FileCheck %s 
--check-prefixes=CHECK,GNU,64
 // RUN: %clang_cc1 -triple arm-none-eabi -emit-llvm -o - %s 
-fsanitize=function -fno-sanitize-recover=all | FileCheck %s 
--check-prefixes=CHECK,ARM,GNU,32
 
+// RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm -o - %s 
-fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s 
--check-prefixes=CHECK,GNU,64,64e
+
 // GNU:  define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] {
 // MSVC: define{{.*}} void @"?fun@@YAXXZ"() #0 !func_sanitize ![[FUNCSAN:.*]] {
 void fun() {}
@@ -13,6 +15,8 @@ void fun() {}
 // ARM:   ptrtoint ptr {{.*}} to i32, !nosanitize !5
 // ARM:   and i32 {{.*}}, -2, !nosanitize !5
 // ARM:   inttoptr i32 {{.*}} to ptr, !nosanitize !5
+// 64e:   %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize
+// 64e:   call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), 
!nosanitize
 // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
 // CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
 // CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-18 Thread Akira Hatanaka via cfe-commits

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


[clang] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification (PR #85886)

2024-07-17 Thread Akira Hatanaka via cfe-commits

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


[clang] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification (PR #85886)

2024-07-17 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/85886

>From d39667c7e65c10babb478d8f8d54fecb66d90568 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 19 Mar 2024 15:50:00 -0700
Subject: [PATCH 1/5] [Sema] Don't drop weak_import from a declaration that
 follows a declaration directly contained in a linkage-specification

Only drop it if the declaration follows a definition. I believe this is
what 33e022650adee965c65f9aea086ee74f3fd1bad5 was trying to do.

rdar://61865848
---
 clang/lib/Sema/SemaDecl.cpp  | 3 +--
 clang/test/SemaCXX/attr-weak.cpp | 7 +++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9a..2e45f1191273a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,8 +4613,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() &&
-  Old->getStorageClass() == SC_None &&
+  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
   !Old->hasAttr()) {
 Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
 Diag(Old->getLocation(), diag::note_previous_declaration);
diff --git a/clang/test/SemaCXX/attr-weak.cpp b/clang/test/SemaCXX/attr-weak.cpp
index f065bfd9483f8..a2c5fd4abd35f 100644
--- a/clang/test/SemaCXX/attr-weak.cpp
+++ b/clang/test/SemaCXX/attr-weak.cpp
@@ -55,3 +55,10 @@ constexpr bool weak_method_is_non_null = 
&WithWeakMember::weak_method != nullptr
 // virtual member function is present.
 constexpr bool virtual_weak_method_is_non_null = 
&WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be 
initialized by a constant expression}}
 // expected-note@-1 {{comparison against pointer to weak member 
'WithWeakMember::virtual_weak_method' can only be performed at runtime}}
+
+// Check that no warnings are emitted.
+extern "C" int g0;
+extern int g0 __attribute__((weak_import));
+
+extern "C" int g1 = 0; // expected-note {{previous definition is here}}
+extern int g1 __attribute__((weak_import)); // expected-warning {{attribute 
declaration must precede definition}}

>From 33e3219c721d0c03f445c9bb977cb9f3809e74ac Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 8 May 2024 20:40:58 -0700
Subject: [PATCH 2/5] Check whether there's a definition at all

---
 clang/lib/Sema/SemaDecl.cpp | 23 +--
 clang/test/Sema/attr-weak.c |  4 
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2e45f1191273a..0be6906026a85 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,12 +4613,23 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
-  !Old->hasAttr()) {
-Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
-Diag(Old->getLocation(), diag::note_previous_declaration);
-// Remove weak_import attribute on new declaration.
-New->dropAttr();
+  if (New->hasAttr()) {
+// We know there's no full definition as the attribute on New would have
+// been removed otherwise. Just look for the most recent tentative
+// definition.
+VarDecl *TentativeDef = nullptr;
+for (auto *D = Old; D; D = D->getPreviousDecl())
+  if (D->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) {
+TentativeDef = D;
+break;
+  }
+
+if (TentativeDef) {
+  Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
+  Diag(TentativeDef->getLocation(), diag::note_previous_declaration);
+  // Remove weak_import attribute on new declaration.
+  New->dropAttr();
+}
   }
 
   if (const auto *ILA = New->getAttr())
diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c
index b827d1539b997..94e1723e125b6 100644
--- a/clang/test/Sema/attr-weak.c
+++ b/clang/test/Sema/attr-weak.c
@@ -19,6 +19,10 @@ static int x __attribute__((weak)); // expected-error {{weak 
declaration cannot
 int C; // expected-note {{previous declaration is here}}
 extern int C __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
 
+int C2; // expected-note {{previous declaration is here}}
+extern int C2;
+extern int C2 __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
+
 static int pr14946_x;
 extern int pr14946_x  __attribute__((weak)); // expected-error {{weak 
declaration cannot have internal linkage}}
 

>From c33375cbc8863be911f7832538228cfde0e1d58d Mon Sep 17 00:00:00 

[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls 
-fptrauth-intrinsics -emit-llvm -o-  
-fptrauth-function-pointer-type-discrimination | FileCheck %s

ahatanak wrote:

Thanks! Please add a line to test linux after this PR is merged.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -351,3 +434,125 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction 
*CGF,
/* IsIsaPointer */ false,
/* AuthenticatesNullValues */ false, Discriminator);
 }
+
+llvm::Value *CodeGenFunction::AuthPointerToPointerCast(llvm::Value *ResultPtr,
+   QualType SourceType,
+   QualType DestType) {
+  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+  if (SourceType->isSignableType())
+CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+  if (DestType->isSignableType())
+NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+  if (!CurAuthInfo && !NewAuthInfo)
+return ResultPtr;
+
+  // If only one side of the cast is a function pointer, then we still need to
+  // resign to handle casts to/from opaque pointers.
+  if (!CurAuthInfo && DestType->isFunctionPointerType())
+CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType);
+
+  if (!NewAuthInfo && SourceType->isFunctionPointerType())
+NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+
+  return EmitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo,
+   /*IsKnownNonNull=*/false);
+}
+
+Address CodeGenFunction::AuthPointerToPointerCast(Address Ptr,
+  QualType SourceType,
+  QualType DestType) {
+  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+  if (SourceType->isSignableType())
+CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+  if (DestType->isSignableType())
+NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+  if (!CurAuthInfo && !NewAuthInfo)
+return Ptr;
+
+  if (!CurAuthInfo && DestType->isFunctionPointerType()) {
+// When casting a non-signed pointer to a function pointer, just set the
+// auth info on Ptr to the assumed schema. The pointer will be resigned to
+// the effective type when used.
+Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType));
+return Ptr;
+  }
+
+  if (!NewAuthInfo && SourceType->isFunctionPointerType()) {
+NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+Ptr = Ptr.getResignedAddress(NewAuthInfo, *this);
+Ptr.setPointerAuthInfo(CGPointerAuthInfo());
+return Ptr;
+  }
+
+  return Ptr;
+}
+
+Address CodeGenFunction::EmitPointerAuthSign(Address Addr,
+ QualType PointeeType) {
+  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+  llvm::Value *Ptr = EmitPointerAuthSign(Info, Addr.emitRawPointer(*this));
+  return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::EmitPointerAuthAuth(Address Addr,
+ QualType PointeeType) {
+  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+  llvm::Value *Ptr = EmitPointerAuthAuth(Info, Addr.emitRawPointer(*this));
+  return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::getAsNaturalAddressOf(Address Addr,
+   QualType PointeeTy) {
+  CGPointerAuthInfo Info =
+  PointeeTy.isNull() ? CGPointerAuthInfo()
+ : CGM.getPointerAuthInfoForPointeeType(PointeeTy);
+  return Addr.getResignedAddress(Info, *this);
+}
+
+Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
+CodeGenFunction &CGF) const {
+  assert(isValid() && "pointer isn't valid");
+  CGPointerAuthInfo CurInfo = getPointerAuthInfo();
+  llvm::Value *Val;
+
+  // Nothing to do if neither the current or the new ptrauth info needs 
signing.
+  if (!CurInfo.isSigned() && !NewInfo.isSigned())
+return Address(getBasePointer(), getElementType(), getAlignment(),
+   isKnownNonNull());
+
+  assert(ElementType && "Effective type has to be set");
+
+  // If the current and the new ptrauth infos are the same and the offset is
+  // null, just cast the base pointer to the effective type.
+  if (CurInfo == NewInfo && !hasOffset())
+Val = getBasePointer();
+  else {
+assert(!Offset && "unexpected non-null offset");
+Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
+NewInfo, isKnownNonNull());
+  }
+
+  Val = CGF.Builder.CreateBitCast(Val, getType());
+  return Address(Val, getElementType(), getAlignment(), NewInfo, nullptr,
+ isKnownNonNull());
+}
+
+llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
+  assert(isSimple());
+  return emitResignedPointer(getType(), CGF);

ahatanak wrote:

Yes, we can check whether there is a noticeable regression in compile time.

https://github.com/llvm/llvm-project/pull/98847
___

[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s  -o - | 
FileCheck -check-prefix=CHECK -check-prefix=NOPCH %s

ahatanak wrote:

Sorry, I just realized the test cases in `ptrauth.c` are duplicates of the ones 
added to `CodeGen/ptrauth-function-type-discriminator.c` and 
`CodeGen/ptrauth-function.c`. I'll remove the file.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -165,6 +166,88 @@ CGPointerAuthInfo 
CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
+static bool isZeroConstant(llvm::Value *value) {
+  if (auto ci = dyn_cast(value))
+return ci->isZero();
+  return false;
+}
+
+static bool equalAuthPolicies(const CGPointerAuthInfo &left,
+  const CGPointerAuthInfo &right) {
+  if (left.isSigned() != right.isSigned())
+return false;
+  assert(left.isSigned() && right.isSigned() &&
+ "should only be called with non-null auth policies");
+  return left.getKey() == right.getKey() &&
+ left.getAuthenticationMode() == right.getAuthenticationMode();
+}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthResign(
+llvm::Value *value, QualType type, const CGPointerAuthInfo &curAuthInfo,
+const CGPointerAuthInfo &newAuthInfo, bool isKnownNonNull) {
+  // Fast path: if neither schema wants a signature, we're done.
+  if (!curAuthInfo && !newAuthInfo)
+return value;
+
+  llvm::Value *null = nullptr;
+  // If the value is obviously null, we're done.
+  if (auto pointerValue = dyn_cast(value->getType())) {
+null = CGM.getNullPointer(pointerValue, type);
+  } else {
+assert(value->getType()->isIntegerTy());
+null = llvm::ConstantInt::get(IntPtrTy, 0);
+  }
+  if (value == null) {
+return value;
+  }
+
+  // If both schemas sign the same way, we're done.
+  if (equalAuthPolicies(curAuthInfo, newAuthInfo)) {

ahatanak wrote:

I don't think we can do that as the function shouldn't return here when 
different discriminators are used. Also we are going to add more stuff to 
`equalAuthPolicies` in the future, so I'll leave it as.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -165,6 +166,88 @@ CGPointerAuthInfo 
CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
+static bool isZeroConstant(llvm::Value *value) {
+  if (auto ci = dyn_cast(value))
+return ci->isZero();
+  return false;
+}
+
+static bool equalAuthPolicies(const CGPointerAuthInfo &left,
+  const CGPointerAuthInfo &right) {
+  if (left.isSigned() != right.isSigned())
+return false;
+  assert(left.isSigned() && right.isSigned() &&
+ "should only be called with non-null auth policies");

ahatanak wrote:

I moved the assertion to the beginning of the function to make it clear that at 
least one side has to be signed.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -165,6 +166,88 @@ CGPointerAuthInfo 
CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
+static bool isZeroConstant(llvm::Value *value) {

ahatanak wrote:

I fixed the names of variables and functions added in this PR.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -3126,3 +3137,57 @@ CodeGenFunction::EmitPointerAuthAuth(const 
CGPointerAuthInfo &PointerAuth,
   return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
llvm::Intrinsic::ptrauth_auth);
 }
+
+llvm::Value *CodeGenFunction::EmitPointerAuthSign(QualType pointeeType,

ahatanak wrote:

I don't think there is any logic behind this choice. The ptrauth-related 
functions in CodeGenFunction.cpp should be moved to CGPointerAuth.cpp.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-16 Thread Akira Hatanaka via cfe-commits


@@ -2373,7 +2373,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
   DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
   return EmitLoadOfLValue(DestLV, CE->getExprLoc());
 }
-return Builder.CreateBitCast(Src, DstTy);
+
+llvm::Value *Result = Builder.CreateBitCast(Src, DstTy);

ahatanak wrote:

Yes, a couple of tests including `test_cast_from_opaque` test this path.

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-14 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Implement function pointer re-signing (PR #98847)

2024-07-14 Thread Akira Hatanaka via cfe-commits

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


[clang] Resign function pointer (PR #98847)

2024-07-14 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Implement function pointer type discrimination (PR #96992)

2024-07-11 Thread Akira Hatanaka via cfe-commits

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


[clang] [PAC] Implement function pointer type discrimination (PR #96992)

2024-07-11 Thread Akira Hatanaka via cfe-commits

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


[clang] [arm64e] Implement function pointer type discrimination (PR #96992)

2024-07-11 Thread Akira Hatanaka via cfe-commits

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-11 Thread Akira Hatanaka via cfe-commits

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-09 Thread Akira Hatanaka via cfe-commits


@@ -3140,6 +3140,269 @@ 
ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) {
   return llvm::getPointerAuthStableSipHash(Str);
 }
 
+/// Encode a function type for use in the discriminator of a function pointer
+/// type. We can't use the itanium scheme for this since C has quite permissive
+/// rules for type compatibility that we need to be compatible with.
+///
+/// Formally, this function associates every function pointer type T with an
+/// encoded string E(T). Let the equivalence relation T1 ~ T2 be defined as
+/// E(T1) == E(T2). E(T) is part of the ABI of values of type T. C type
+/// compatibility requires equivalent treatment under the ABI, so
+/// CCompatible(T1, T2) must imply E(T1) == E(T2), that is, CCompatible must be
+/// a subset of ~. Crucially, however, it must be a proper subset because
+/// CCompatible is not an equivalence relation: for example, int[] is 
compatible
+/// with both int[1] and int[2], but the latter are not compatible with each
+/// other. Therefore this encoding function must be careful to only distinguish
+/// types if there is no third type with which they are both required to be
+/// compatible.
+static void encodeTypeForFunctionPointerAuth(ASTContext &Ctx, raw_ostream &OS,
+ QualType QT) {
+  // FIXME: Consider address space qualifiers.
+  const Type *T = QT.getCanonicalType().getTypePtr();
+
+  // FIXME: Consider using the C++ type mangling when we encounter a construct
+  // that is incompatible with C.
+
+  switch (T->getTypeClass()) {
+  case Type::Atomic:
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getValueType());
+
+  case Type::LValueReference:
+OS << "R";
+encodeTypeForFunctionPointerAuth(Ctx, OS,
+ cast(T)->getPointeeType());
+return;
+  case Type::RValueReference:
+OS << "O";
+encodeTypeForFunctionPointerAuth(Ctx, OS,
+ cast(T)->getPointeeType());
+return;
+
+  case Type::Pointer:
+// C11 6.7.6.1p2:
+//   For two pointer types to be compatible, both shall be identically
+//   qualified and both shall be pointers to compatible types.
+// FIXME: we should also consider pointee types.
+OS << "P";
+return;
+
+  case Type::ObjCObjectPointer:
+  case Type::BlockPointer:
+OS << "P";
+return;
+
+  case Type::Complex:
+OS << "C";
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getElementType());
+
+  case Type::VariableArray:
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::ArrayParameter:
+// C11 6.7.6.2p6:
+//   For two array types to be compatible, both shall have compatible
+//   element types, and if both size specifiers are present, and are 
integer
+//   constant expressions, then both size specifiers shall have the same
+//   constant value [...]
+//
+// So since ElemType[N] has to be compatible ElemType[], we can't encode 
the
+// width of the array.
+OS << "A";
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getElementType());
+
+  case Type::ObjCInterface:
+  case Type::ObjCObject:
+OS << "";
+return;
+
+  case Type::Enum:
+// C11 6.7.2.2p4:
+//   Each enumerated type shall be compatible with char, a signed integer
+//   type, or an unsigned integer type.
+//
+// So we have to treat enum types as integers.
+OS << "i";
+return;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto: {
+// C11 6.7.6.3p15:
+//   For two function types to be compatible, both shall specify compatible
+//   return types. Moreover, the parameter type lists, if both are present,
+//   shall agree in the number of parameters and in the use of the ellipsis
+//   terminator; corresponding parameters shall have compatible types.
+//
+// That paragraph goes on to describe how unprototyped functions are to be
+// handled, which we ignore here. Unprototyped function pointers are hashed
+// as though they were prototyped nullary functions since thats probably
+// what the user meant. This behavior is non-conforming.
+// FIXME: If we add a "custom discriminator" function type attribute we
+// should encode functions as their discriminators.
+OS << "F";
+auto *FuncType = cast(T);
+encodeTypeForFunctionPointerAuth(Ctx, OS, FuncType->getReturnType());
+if (auto *FPT = dyn_cast(FuncType)) {
+  for (QualType Param : FPT->param_types()) {
+Param = Ctx.getSignatureParameterType(Param);
+encodeTypeForFunctionPointerAuth(Ctx, OS, Param);
+  }
+  if (FPT->isVariadic())
+OS << "z";
+}
+OS << "E";
+return;
+  }
+
+  case Type::MemberPointer: {
+OS << "M";
+auto *MPT = T->getAs();
+encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
+encodeTypeForFunctionP

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-09 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96992

>From cf22a4be007f7e6fdc6e4c17c1f32fa70440b123 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 26 Jun 2024 13:02:31 -0700
Subject: [PATCH 1/5] [clang] Implement function pointer type discrimination

Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall 
---
 clang/include/clang/AST/ASTContext.h  |   3 +
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Features.def|   1 +
 clang/include/clang/Basic/LangOptions.def |   3 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   4 +
 clang/include/clang/Driver/Options.td |   2 +
 clang/lib/AST/ASTContext.cpp  | 263 ++
 clang/lib/CodeGen/CGExprConstant.cpp  |   5 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  68 -
 clang/lib/CodeGen/CodeGenModule.h |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp |   3 +
 clang/lib/Frontend/CompilerInvocation.cpp |  11 +-
 .../ptrauth-function-type-discriminator.c | 137 +
 clang/test/Preprocessor/ptrauth_feature.c |  34 ++-
 14 files changed, 528 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator.c

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase {
   uint16_t
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
+  /// Return the "other" type-specific discriminator for the given type.
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
   /// qualifiers on ObjCObjectPointerType. It can be set to true when
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a98899f7f4222..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2506,6 +2506,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8001,6 +8002,8 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
+inline bool Type::isSignableType() const { return isPointerType(); }
+
 inline bool Type::isBlockPointerType() const {
   return isa(CanonicalType);
 }
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..3c9d0364880c5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, 
LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, 
LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, 
LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_function_pointer_type_discrimination, 
LangOpts.FunctionPointerTypeDiscrimination)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 6dd6b5614f44c..554f8643812b5 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,
+   "Use type discrimination when signing function pointers")
+
 ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, 
SignReturnAddressScopeKind::None,
  "Scope of return address signing")
 ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, 
SignReturnAddressKeyKind::AKey,
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index d4822dc160082..9cbc5a8a2a3f4 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 /// Return a declaration discriminator for the given global decl.
 uint16_t getPointerAuthDeclDiscriminator(CodeGenModule

[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-07-09 Thread Akira Hatanaka via cfe-commits

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


[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-07-08 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96944

>From d21bdaec94a169b27e7f7bace399e77bf99fd572 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 25 Jun 2024 19:37:46 -0700
Subject: [PATCH 1/2] [CodeGen] Add a flag to disable emitting block signature
 strings

Users who don't need the signature string to be emitted can use the flag
to reduce code size.

rdar://121933818
---
 clang/docs/ReleaseNotes.rst  |  5 
 clang/include/clang/Basic/CodeGenOptions.def |  1 +
 clang/include/clang/Driver/Options.td|  5 
 clang/lib/CodeGen/CGBlocks.cpp   | 24 +---
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 clang/test/CodeGen/blocks.c  | 12 ++
 clang/test/CodeGenObjC/blocks.m  |  8 +--
 7 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index da967fcdda808..d94fb73fa2c7c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -420,6 +420,11 @@ New Compiler Flags
   Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when
   MSVC compatibility mode is used. It has no effect for C++ code.
 
+- ``-fdisable-block-signature-string`` instructs clang not to emit the 
signature
+  string for blocks. Disabling the string can potentially break existing code
+  that relies on it. Users should carefully consider this possibiilty when 
using
+  the flag.
+
 Deprecated Compiler Flags
 -
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index e3f6da4a84f69..d8738541266d5 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -187,6 +187,7 @@ CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when 
-mno-implicit-float is enable
 CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is 
defined.
 CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< 
-cl-fp32-correctly-rounded-divide-sqrt
 CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< 
-fno-hip-fp32-correctly-rounded-divide-sqrt
+CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when 
-fdisable-block-signature-string is enabled.
 CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is 
enabled.
 CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get 
unique names.
 CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using 
profile information.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index dd55838dcf384..53a5a918cf52d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3477,6 +3477,11 @@ defm objc_avoid_heapify_local_blocks : 
BoolFOption<"objc-avoid-heapify-local-blo
   PosFlag,
   NegFlag,
   BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+defm disable_block_signature_string : 
BoolFOption<"disable-block-signature-string",
+  CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
+  PosFlag,
+  NegFlag,
+  BothFlags<[], [CC1Option], " block signature string)">>;
 
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group,
   Visibility<[ClangOption, FlangOption]>,
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 5dac1cd425bf6..241d6fc2a0c95 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -121,11 +121,15 @@ static std::string getBlockDescriptorName(const 
CGBlockInfo &BlockInfo,
 Name += "_";
   }
 
-  std::string TypeAtEncoding =
-  CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
-  /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
-  /// a separator between symbol name and symbol version.
-  std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  std::string TypeAtEncoding;
+
+  if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {
+TypeAtEncoding =
+CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
+/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms
+/// as a separator between symbol name and symbol version.
+std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  }
   Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
   Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
   return Name;
@@ -201,9 +205,13 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule 
&CGM,
   }
 
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.
-  std::string typeAtEncoding =
-CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
-  elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer());
+  if (CGM.getCodeGenOpts().DisableBlockSignatureString) {
+elements.addNullPoin

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-08 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96992

>From cf22a4be007f7e6fdc6e4c17c1f32fa70440b123 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 26 Jun 2024 13:02:31 -0700
Subject: [PATCH 1/4] [clang] Implement function pointer type discrimination

Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall 
---
 clang/include/clang/AST/ASTContext.h  |   3 +
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Features.def|   1 +
 clang/include/clang/Basic/LangOptions.def |   3 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   4 +
 clang/include/clang/Driver/Options.td |   2 +
 clang/lib/AST/ASTContext.cpp  | 263 ++
 clang/lib/CodeGen/CGExprConstant.cpp  |   5 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  68 -
 clang/lib/CodeGen/CodeGenModule.h |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp |   3 +
 clang/lib/Frontend/CompilerInvocation.cpp |  11 +-
 .../ptrauth-function-type-discriminator.c | 137 +
 clang/test/Preprocessor/ptrauth_feature.c |  34 ++-
 14 files changed, 528 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator.c

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase {
   uint16_t
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
+  /// Return the "other" type-specific discriminator for the given type.
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
   /// qualifiers on ObjCObjectPointerType. It can be set to true when
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a98899f7f4222..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2506,6 +2506,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8001,6 +8002,8 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
+inline bool Type::isSignableType() const { return isPointerType(); }
+
 inline bool Type::isBlockPointerType() const {
   return isa(CanonicalType);
 }
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..3c9d0364880c5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, 
LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, 
LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, 
LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_function_pointer_type_discrimination, 
LangOpts.FunctionPointerTypeDiscrimination)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 6dd6b5614f44c..554f8643812b5 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,
+   "Use type discrimination when signing function pointers")
+
 ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, 
SignReturnAddressScopeKind::None,
  "Scope of return address signing")
 ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, 
SignReturnAddressKeyKind::AKey,
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index d4822dc160082..9cbc5a8a2a3f4 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 /// Return a declaration discriminator for the given global decl.
 uint16_t getPointerAuthDeclDiscriminator(CodeGenModule

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-08 Thread Akira Hatanaka via cfe-commits


@@ -5,55 +5,65 @@
 // RUN:   -fptrauth-vtable-pointer-address-discrimination \
 // RUN:   -fptrauth-vtable-pointer-type-discrimination \
 // RUN:   -fptrauth-init-fini | \
-// RUN:   FileCheck %s 
--check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+// RUN:   FileCheck %s 
--check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI,NOFUNC

ahatanak wrote:

We can clean up the tests in another PR. It seems to me that it's better to 
test one feature at a time.

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


[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-07-03 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96944

>From d21bdaec94a169b27e7f7bace399e77bf99fd572 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 25 Jun 2024 19:37:46 -0700
Subject: [PATCH 1/2] [CodeGen] Add a flag to disable emitting block signature
 strings

Users who don't need the signature string to be emitted can use the flag
to reduce code size.

rdar://121933818
---
 clang/docs/ReleaseNotes.rst  |  5 
 clang/include/clang/Basic/CodeGenOptions.def |  1 +
 clang/include/clang/Driver/Options.td|  5 
 clang/lib/CodeGen/CGBlocks.cpp   | 24 +---
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 clang/test/CodeGen/blocks.c  | 12 ++
 clang/test/CodeGenObjC/blocks.m  |  8 +--
 7 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index da967fcdda808..d94fb73fa2c7c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -420,6 +420,11 @@ New Compiler Flags
   Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when
   MSVC compatibility mode is used. It has no effect for C++ code.
 
+- ``-fdisable-block-signature-string`` instructs clang not to emit the 
signature
+  string for blocks. Disabling the string can potentially break existing code
+  that relies on it. Users should carefully consider this possibiilty when 
using
+  the flag.
+
 Deprecated Compiler Flags
 -
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index e3f6da4a84f69..d8738541266d5 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -187,6 +187,7 @@ CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when 
-mno-implicit-float is enable
 CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is 
defined.
 CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< 
-cl-fp32-correctly-rounded-divide-sqrt
 CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< 
-fno-hip-fp32-correctly-rounded-divide-sqrt
+CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when 
-fdisable-block-signature-string is enabled.
 CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is 
enabled.
 CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get 
unique names.
 CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using 
profile information.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index dd55838dcf384..53a5a918cf52d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3477,6 +3477,11 @@ defm objc_avoid_heapify_local_blocks : 
BoolFOption<"objc-avoid-heapify-local-blo
   PosFlag,
   NegFlag,
   BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+defm disable_block_signature_string : 
BoolFOption<"disable-block-signature-string",
+  CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
+  PosFlag,
+  NegFlag,
+  BothFlags<[], [CC1Option], " block signature string)">>;
 
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group,
   Visibility<[ClangOption, FlangOption]>,
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 5dac1cd425bf6..241d6fc2a0c95 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -121,11 +121,15 @@ static std::string getBlockDescriptorName(const 
CGBlockInfo &BlockInfo,
 Name += "_";
   }
 
-  std::string TypeAtEncoding =
-  CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
-  /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
-  /// a separator between symbol name and symbol version.
-  std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  std::string TypeAtEncoding;
+
+  if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {
+TypeAtEncoding =
+CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
+/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms
+/// as a separator between symbol name and symbol version.
+std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  }
   Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
   Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
   return Name;
@@ -201,9 +205,13 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule 
&CGM,
   }
 
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.
-  std::string typeAtEncoding =
-CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
-  elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer());
+  if (CGM.getCodeGenOpts().DisableBlockSignatureString) {
+elements.addNullPoin

[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-07-03 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

Sorry, I didn't remember that I had to set `BLOCK_HAS_SIGNATURE` to 0.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-02 Thread Akira Hatanaka via cfe-commits


@@ -2220,6 +2220,11 @@ llvm::Constant 
*ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) {
 
   // The assertions here are all checked by Sema.
   assert(Result.Val.isLValue());
+  auto *Base = Result.Val.getLValueBase().get();
+  if (auto *Decl = dyn_cast_or_null(Base)) {
+assert(Result.Val.getLValueOffset().isZero());
+return CGM.getRawFunctionPointer(Decl);

ahatanak wrote:

Just noticed that there's an unnecessary null check in the code above.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-02 Thread Akira Hatanaka via cfe-commits


@@ -3140,6 +3140,269 @@ 
ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) {
   return llvm::getPointerAuthStableSipHash(Str);
 }
 
+/// Encode a function type for use in the discriminator of a function pointer
+/// type. We can't use the itanium scheme for this since C has quite permissive
+/// rules for type compatibility that we need to be compatible with.
+///
+/// Formally, this function associates every function pointer type T with an
+/// encoded string E(T). Let the equivalence relation T1 ~ T2 be defined as
+/// E(T1) == E(T2). E(T) is part of the ABI of values of type T. C type
+/// compatibility requires equivalent treatment under the ABI, so
+/// CCompatible(T1, T2) must imply E(T1) == E(T2), that is, CCompatible must be
+/// a subset of ~. Crucially, however, it must be a proper subset because
+/// CCompatible is not an equivalence relation: for example, int[] is 
compatible
+/// with both int[1] and int[2], but the latter are not compatible with each
+/// other. Therefore this encoding function must be careful to only distinguish
+/// types if there is no third type with which they are both required to be
+/// compatible.
+static void encodeTypeForFunctionPointerAuth(ASTContext &Ctx, raw_ostream &OS,
+ QualType QT) {
+  // FIXME: Consider address space qualifiers.
+  const Type *T = QT.getCanonicalType().getTypePtr();
+
+  // FIXME: Consider using the C++ type mangling when we encounter a construct
+  // that is incompatible with C.
+
+  switch (T->getTypeClass()) {
+  case Type::Atomic:
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getValueType());
+
+  case Type::LValueReference:
+OS << "R";
+encodeTypeForFunctionPointerAuth(Ctx, OS,
+ cast(T)->getPointeeType());
+return;
+  case Type::RValueReference:
+OS << "O";
+encodeTypeForFunctionPointerAuth(Ctx, OS,
+ cast(T)->getPointeeType());
+return;
+
+  case Type::Pointer:
+// C11 6.7.6.1p2:
+//   For two pointer types to be compatible, both shall be identically
+//   qualified and both shall be pointers to compatible types.
+// FIXME: we should also consider pointee types.
+OS << "P";
+return;
+
+  case Type::ObjCObjectPointer:
+  case Type::BlockPointer:
+OS << "P";
+return;
+
+  case Type::Complex:
+OS << "C";
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getElementType());
+
+  case Type::VariableArray:
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::ArrayParameter:
+// C11 6.7.6.2p6:
+//   For two array types to be compatible, both shall have compatible
+//   element types, and if both size specifiers are present, and are 
integer
+//   constant expressions, then both size specifiers shall have the same
+//   constant value [...]
+//
+// So since ElemType[N] has to be compatible ElemType[], we can't encode 
the
+// width of the array.
+OS << "A";
+return encodeTypeForFunctionPointerAuth(
+Ctx, OS, cast(T)->getElementType());
+
+  case Type::ObjCInterface:
+  case Type::ObjCObject:
+OS << "";
+return;
+
+  case Type::Enum:
+// C11 6.7.2.2p4:
+//   Each enumerated type shall be compatible with char, a signed integer
+//   type, or an unsigned integer type.
+//
+// So we have to treat enum types as integers.
+OS << "i";
+return;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto: {
+// C11 6.7.6.3p15:
+//   For two function types to be compatible, both shall specify compatible
+//   return types. Moreover, the parameter type lists, if both are present,
+//   shall agree in the number of parameters and in the use of the ellipsis
+//   terminator; corresponding parameters shall have compatible types.
+//
+// That paragraph goes on to describe how unprototyped functions are to be
+// handled, which we ignore here. Unprototyped function pointers are hashed
+// as though they were prototyped nullary functions since thats probably
+// what the user meant. This behavior is non-conforming.
+// FIXME: If we add a "custom discriminator" function type attribute we
+// should encode functions as their discriminators.
+OS << "F";
+auto *FuncType = cast(T);
+encodeTypeForFunctionPointerAuth(Ctx, OS, FuncType->getReturnType());
+if (auto *FPT = dyn_cast(FuncType)) {
+  for (QualType Param : FPT->param_types()) {
+Param = Ctx.getSignatureParameterType(Param);
+encodeTypeForFunctionPointerAuth(Ctx, OS, Param);
+  }
+  if (FPT->isVariadic())
+OS << "z";
+}
+OS << "E";
+return;
+  }
+
+  case Type::MemberPointer: {
+OS << "M";
+auto *MPT = T->getAs();
+encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
+encodeTypeForFunctionP

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-07-02 Thread Akira Hatanaka via cfe-commits


@@ -2220,6 +2220,11 @@ llvm::Constant 
*ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) {
 
   // The assertions here are all checked by Sema.
   assert(Result.Val.isLValue());
+  auto *Base = Result.Val.getLValueBase().get();
+  if (auto *Decl = dyn_cast_or_null(Base)) {
+assert(Result.Val.getLValueOffset().isZero());
+return CGM.getRawFunctionPointer(Decl);

ahatanak wrote:

The checks in `SemaChecking.cpp` and the assertion in `emitPointerAuthPointer` 
ensure that the expression of the first argument to 
`__builtin_ptrauth_sign_constant` evaluates to an `LValue` with a `ValueDecl` 
base. With that restriction, a call to `emitAbstract` returns a signed pointer 
only when the argument points to a function definition (see 
`ConstantLValueEmitter::tryEmitBase`). Since we are special-casing functions 
here, the call to `emitAbstract` returns an unsigned pointer.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits


@@ -2220,6 +2220,11 @@ llvm::Constant 
*ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) {
 
   // The assertions here are all checked by Sema.
   assert(Result.Val.isLValue());
+  auto *Base = Result.Val.getLValueBase().get();
+  if (auto *Decl = dyn_cast_or_null(Base)) {
+assert(Result.Val.getLValueOffset().isZero());
+return CGM.getRawFunctionPointer(Decl);

ahatanak wrote:

This function is called to return an unsigned pointer. The returned pointer is 
used to create a signed pointer for `__builtin_ptrauth_sign_constant` in 
`emitPointerAuthSignConstant`. `ConstantEmitter` returns a pointer that is 
signed with zero or a non-zero discriminator that is based on the function type 
etc.



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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96992

>From cf22a4be007f7e6fdc6e4c17c1f32fa70440b123 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 26 Jun 2024 13:02:31 -0700
Subject: [PATCH 1/3] [clang] Implement function pointer type discrimination

Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall 
---
 clang/include/clang/AST/ASTContext.h  |   3 +
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Features.def|   1 +
 clang/include/clang/Basic/LangOptions.def |   3 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   4 +
 clang/include/clang/Driver/Options.td |   2 +
 clang/lib/AST/ASTContext.cpp  | 263 ++
 clang/lib/CodeGen/CGExprConstant.cpp  |   5 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  68 -
 clang/lib/CodeGen/CodeGenModule.h |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp |   3 +
 clang/lib/Frontend/CompilerInvocation.cpp |  11 +-
 .../ptrauth-function-type-discriminator.c | 137 +
 clang/test/Preprocessor/ptrauth_feature.c |  34 ++-
 14 files changed, 528 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator.c

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase {
   uint16_t
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
+  /// Return the "other" type-specific discriminator for the given type.
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
   /// qualifiers on ObjCObjectPointerType. It can be set to true when
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a98899f7f4222..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2506,6 +2506,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8001,6 +8002,8 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
+inline bool Type::isSignableType() const { return isPointerType(); }
+
 inline bool Type::isBlockPointerType() const {
   return isa(CanonicalType);
 }
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..3c9d0364880c5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, 
LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, 
LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, 
LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_function_pointer_type_discrimination, 
LangOpts.FunctionPointerTypeDiscrimination)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 6dd6b5614f44c..554f8643812b5 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,
+   "Use type discrimination when signing function pointers")
+
 ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, 
SignReturnAddressScopeKind::None,
  "Scope of return address signing")
 ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, 
SignReturnAddressKeyKind::AKey,
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index d4822dc160082..9cbc5a8a2a3f4 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 /// Return a declaration discriminator for the given global decl.
 uint16_t getPointerAuthDeclDiscriminator(CodeGenModule

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits


@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,

ahatanak wrote:

I moved the langopt closer to other pointer auth langopts. I think we can 
convert other pointer auth langopts to `BENIGN_LANGOPT` or 
`BENIGN_ENUM_LANGOPT` as they probably don't affect the construction of the AST.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits


@@ -3140,6 +3140,269 @@ 
ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) {
   return llvm::getPointerAuthStableSipHash(Str);
 }
 
+/// Encode a function type for use in the discriminator of a function pointer
+/// type. We can't use the itanium scheme for this since C has quite permissive
+/// rules for type compatibility that we need to be compatible with.
+///
+/// Formally, this function associates every function pointer type T with an
+/// encoded string E(T). Let the equivalence relation T1 ~ T2 be defined as
+/// E(T1) == E(T2). E(T) is part of the ABI of values of type T. C type
+/// compatibility requires equivalent treatment under the ABI, so
+/// CCompatible(T1, T2) must imply E(T1) == E(T2), that is, CCompatible must be
+/// a subset of ~. Crucially, however, it must be a proper subset because
+/// CCompatible is not an equivalence relation: for example, int[] is 
compatible
+/// with both int[1] and int[2], but the latter are not compatible with each
+/// other. Therefore this encoding function must be careful to only distinguish
+/// types if there is no third type with which they are both required to be
+/// compatible.
+static void encodeTypeForFunctionPointerAuth(ASTContext &Ctx, raw_ostream &OS,

ahatanak wrote:

We can add use `__builtin_ptrauth_type_discriminator`, which hasn't been 
upstreamed yet, and `__builtin_ptrauth_string_discriminator` to test function 
type discriminators in a subsequent patch.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96992

>From cf22a4be007f7e6fdc6e4c17c1f32fa70440b123 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 26 Jun 2024 13:02:31 -0700
Subject: [PATCH 1/2] [clang] Implement function pointer type discrimination

Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall 
---
 clang/include/clang/AST/ASTContext.h  |   3 +
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Features.def|   1 +
 clang/include/clang/Basic/LangOptions.def |   3 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   4 +
 clang/include/clang/Driver/Options.td |   2 +
 clang/lib/AST/ASTContext.cpp  | 263 ++
 clang/lib/CodeGen/CGExprConstant.cpp  |   5 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  68 -
 clang/lib/CodeGen/CodeGenModule.h |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp |   3 +
 clang/lib/Frontend/CompilerInvocation.cpp |  11 +-
 .../ptrauth-function-type-discriminator.c | 137 +
 clang/test/Preprocessor/ptrauth_feature.c |  34 ++-
 14 files changed, 528 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator.c

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase {
   uint16_t
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
+  /// Return the "other" type-specific discriminator for the given type.
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
   /// qualifiers on ObjCObjectPointerType. It can be set to true when
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a98899f7f4222..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2506,6 +2506,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8001,6 +8002,8 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
+inline bool Type::isSignableType() const { return isPointerType(); }
+
 inline bool Type::isBlockPointerType() const {
   return isa(CanonicalType);
 }
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..3c9d0364880c5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, 
LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, 
LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, 
LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_function_pointer_type_discrimination, 
LangOpts.FunctionPointerTypeDiscrimination)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 6dd6b5614f44c..554f8643812b5 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,
+   "Use type discrimination when signing function pointers")
+
 ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, 
SignReturnAddressScopeKind::None,
  "Scope of return address signing")
 ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, 
SignReturnAddressKeyKind::AKey,
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index d4822dc160082..9cbc5a8a2a3f4 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 /// Return a declaration discriminator for the given global decl.
 uint16_t getPointerAuthDeclDiscriminator(CodeGenModule

[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-27 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/96992

Give users an option to sign a function pointer using a non-zero discrimiantor 
based on the type of the destination.

>From cf22a4be007f7e6fdc6e4c17c1f32fa70440b123 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 26 Jun 2024 13:02:31 -0700
Subject: [PATCH] [clang] Implement function pointer type discrimination

Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall 
---
 clang/include/clang/AST/ASTContext.h  |   3 +
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Features.def|   1 +
 clang/include/clang/Basic/LangOptions.def |   3 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   4 +
 clang/include/clang/Driver/Options.td |   2 +
 clang/lib/AST/ASTContext.cpp  | 263 ++
 clang/lib/CodeGen/CGExprConstant.cpp  |   5 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  68 -
 clang/lib/CodeGen/CodeGenModule.h |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp |   3 +
 clang/lib/Frontend/CompilerInvocation.cpp |  11 +-
 .../ptrauth-function-type-discriminator.c | 137 +
 clang/test/Preprocessor/ptrauth_feature.c |  34 ++-
 14 files changed, 528 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator.c

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index a99f2dc6eb3f2..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase {
   uint16_t
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
+  /// Return the "other" type-specific discriminator for the given type.
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
   /// qualifiers on ObjCObjectPointerType. It can be set to true when
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a98899f7f4222..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2506,6 +2506,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8001,6 +8002,8 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
+inline bool Type::isSignableType() const { return isPointerType(); }
+
 inline bool Type::isBlockPointerType() const {
   return isa(CanonicalType);
 }
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 53f410d3cb4bd..3c9d0364880c5 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, 
LangOpts.PointerAuthVTPtr
 FEATURE(ptrauth_vtable_pointer_type_discrimination, 
LangOpts.PointerAuthVTPtrTypeDiscrimination)
 FEATURE(ptrauth_member_function_pointer_type_discrimination, 
LangOpts.PointerAuthCalls)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
+FEATURE(ptrauth_function_pointer_type_discrimination, 
LangOpts.FunctionPointerTypeDiscrimination)
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 6dd6b5614f44c..554f8643812b5 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -470,6 +470,9 @@ ENUM_LANGOPT(StrictFlexArraysLevel, 
StrictFlexArraysLevelKind, 2,
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 
+BENIGN_LANGOPT(FunctionPointerTypeDiscrimination, 1, 0,
+   "Use type discrimination when signing function pointers")
+
 ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, 
SignReturnAddressScopeKind::None,
  "Scope of return address signing")
 ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, 
SignReturnAddressKeyKind::AKey,
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index d4822dc160082..9cbc5a8a2a3f4 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 /// Re

[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-06-27 Thread Akira Hatanaka via cfe-commits

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


[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-06-27 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/96944

>From d21bdaec94a169b27e7f7bace399e77bf99fd572 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 25 Jun 2024 19:37:46 -0700
Subject: [PATCH] [CodeGen] Add a flag to disable emitting block signature
 strings

Users who don't need the signature string to be emitted can use the flag
to reduce code size.

rdar://121933818
---
 clang/docs/ReleaseNotes.rst  |  5 
 clang/include/clang/Basic/CodeGenOptions.def |  1 +
 clang/include/clang/Driver/Options.td|  5 
 clang/lib/CodeGen/CGBlocks.cpp   | 24 +---
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 clang/test/CodeGen/blocks.c  | 12 ++
 clang/test/CodeGenObjC/blocks.m  |  8 +--
 7 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index da967fcdda808..d94fb73fa2c7c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -420,6 +420,11 @@ New Compiler Flags
   Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when
   MSVC compatibility mode is used. It has no effect for C++ code.
 
+- ``-fdisable-block-signature-string`` instructs clang not to emit the 
signature
+  string for blocks. Disabling the string can potentially break existing code
+  that relies on it. Users should carefully consider this possibiilty when 
using
+  the flag.
+
 Deprecated Compiler Flags
 -
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index e3f6da4a84f69..d8738541266d5 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -187,6 +187,7 @@ CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when 
-mno-implicit-float is enable
 CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is 
defined.
 CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< 
-cl-fp32-correctly-rounded-divide-sqrt
 CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< 
-fno-hip-fp32-correctly-rounded-divide-sqrt
+CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when 
-fdisable-block-signature-string is enabled.
 CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is 
enabled.
 CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get 
unique names.
 CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using 
profile information.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index dd55838dcf384..53a5a918cf52d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3477,6 +3477,11 @@ defm objc_avoid_heapify_local_blocks : 
BoolFOption<"objc-avoid-heapify-local-blo
   PosFlag,
   NegFlag,
   BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+defm disable_block_signature_string : 
BoolFOption<"disable-block-signature-string",
+  CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
+  PosFlag,
+  NegFlag,
+  BothFlags<[], [CC1Option], " block signature string)">>;
 
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group,
   Visibility<[ClangOption, FlangOption]>,
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 5dac1cd425bf6..241d6fc2a0c95 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -121,11 +121,15 @@ static std::string getBlockDescriptorName(const 
CGBlockInfo &BlockInfo,
 Name += "_";
   }
 
-  std::string TypeAtEncoding =
-  CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
-  /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
-  /// a separator between symbol name and symbol version.
-  std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  std::string TypeAtEncoding;
+
+  if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {
+TypeAtEncoding =
+CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
+/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms
+/// as a separator between symbol name and symbol version.
+std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  }
   Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
   Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
   return Name;
@@ -201,9 +205,13 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule 
&CGM,
   }
 
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.
-  std::string typeAtEncoding =
-CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
-  elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer());
+  if (CGM.getCodeGenOpts().DisableBlockSignatureString) {
+elements.addNullPointer(

[clang] [CodeGen] Add a flag to disable emitting block signature strings (PR #96944)

2024-06-27 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/96944

Users who don't need the signature string to be emitted can use the flag to 
reduce code size.

rdar://121933818

>From 5f71f113b27482114904eae8234c6ebc17eef5a4 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 25 Jun 2024 19:37:46 -0700
Subject: [PATCH] [CodeGen] Add a flag to disable emitting block signature
 strings

Users who don't need the signature string to be emitted can use the flag
to reduce code size.

rdar://121933818
---
 clang/docs/ReleaseNotes.rst  |  5 
 clang/include/clang/Basic/CodeGenOptions.def |  1 +
 clang/include/clang/Driver/Options.td|  5 
 clang/lib/CodeGen/CGBlocks.cpp   | 24 +---
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 clang/test/CodeGen/blocks.c  | 12 ++
 clang/test/CodeGenObjC/blocks.m  |  8 +--
 7 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index df579ae398c5e..f1fe826edc0ab 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -419,6 +419,11 @@ New Compiler Flags
   Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when
   MSVC compatibility mode is used. It has no effect for C++ code.
 
+- ``-fdisable-block-signature-string`` instructs clang not to emit the 
signature
+  string for blocks. Disabling the string can potentially break existing code
+  that relies on it. Users should carefully consider this possibiilty when 
using
+  the flag.
+
 Deprecated Compiler Flags
 -
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index e3f6da4a84f69..d8738541266d5 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -187,6 +187,7 @@ CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when 
-mno-implicit-float is enable
 CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is 
defined.
 CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< 
-cl-fp32-correctly-rounded-divide-sqrt
 CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< 
-fno-hip-fp32-correctly-rounded-divide-sqrt
+CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when 
-fdisable-block-signature-string is enabled.
 CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is 
enabled.
 CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get 
unique names.
 CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using 
profile information.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index dd55838dcf384..53a5a918cf52d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3477,6 +3477,11 @@ defm objc_avoid_heapify_local_blocks : 
BoolFOption<"objc-avoid-heapify-local-blo
   PosFlag,
   NegFlag,
   BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+defm disable_block_signature_string : 
BoolFOption<"disable-block-signature-string",
+  CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
+  PosFlag,
+  NegFlag,
+  BothFlags<[], [CC1Option], " block signature string)">>;
 
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group,
   Visibility<[ClangOption, FlangOption]>,
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 5dac1cd425bf6..241d6fc2a0c95 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -121,11 +121,15 @@ static std::string getBlockDescriptorName(const 
CGBlockInfo &BlockInfo,
 Name += "_";
   }
 
-  std::string TypeAtEncoding =
-  CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
-  /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
-  /// a separator between symbol name and symbol version.
-  std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  std::string TypeAtEncoding;
+
+  if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {
+TypeAtEncoding =
+CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
+/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms
+/// as a separator between symbol name and symbol version.
+std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
+  }
   Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
   Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
   return Name;
@@ -201,9 +205,13 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule 
&CGM,
   }
 
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.
-  std::string typeAtEncoding =
-CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
-  elements.add(CGM.GetAddrOfConstantCString(typeA

[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-25 Thread Akira Hatanaka via cfe-commits

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


[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-25 Thread Akira Hatanaka via cfe-commits

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


[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-24 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/79230

>From 95200f3bb3859738981240a9d8c503a13ede9601 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 16 Jan 2024 13:18:09 -0800
Subject: [PATCH 01/19] Add support for builtin_verbose_trap

The builtin causes the program to stop its execution abnormally and shows a
human-readable description of the reason for the termination when a debugger is
attached or in a symbolicated crash log.

The motivation for the builtin is explained in the following RFC:

https://discourse.llvm.org/t/rfc-adding-builtin-verbose-trap-string-literal/75845
---
 clang/docs/LanguageExtensions.rst | 49 ++-
 clang/include/clang/AST/Expr.h|  5 ++
 clang/include/clang/Basic/Builtins.td |  6 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/AST/ExprConstant.cpp| 18 +--
 clang/lib/CodeGen/CGBuiltin.cpp   | 12 +
 clang/lib/CodeGen/CGDebugInfo.cpp | 42 
 clang/lib/CodeGen/CGDebugInfo.h   | 20 
 clang/lib/Sema/SemaChecking.cpp   | 22 +
 .../CodeGenCXX/debug-info-verbose-trap.cpp| 49 +++
 clang/test/SemaCXX/verbose-trap.cpp   | 28 +++
 11 files changed, 249 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/debug-info-verbose-trap.cpp
 create mode 100644 clang/test/SemaCXX/verbose-trap.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 84fc4dee02fa8..1dd8d3bcec920 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3467,6 +3467,54 @@ Query for this feature with 
``__has_builtin(__builtin_trap)``.
 
 ``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and 
then to ``brk #payload``.
 
+``__builtin_verbose_trap``
+--
+
+``__builtin_verbose_trap`` causes the program to stop its execution abnormally
+and shows a human-readable description of the reason for the termination when a
+debugger is attached or in a symbolicated crash log.
+
+**Syntax**:
+
+.. code-block:: c++
+
+__builtin_verbose_trap(const char *reason)
+
+**Description**
+
+``__builtin_verbose_trap`` is lowered to the ` ``llvm.trap`` 
`_ builtin.
+Additionally, clang emits debug metadata that represents an artificial inline
+frame whose name encodes the string passed to the builtin, prefixed by a 
"magic"
+prefix.
+
+For example, consider the following code:
+
+.. code-block:: c++
+
+void foo(int* p) {
+  if (p == nullptr)
+__builtin_verbose_trap("Argument_must_not_be_null");
+}
+
+The debug metadata would look as if it were produced for the following code:
+
+.. code-block:: c++
+
+__attribute__((always_inline))
+inline void "__llvm_verbose_trap: Argument_must_not_be_null"() {
+  __builtin_trap();
+}
+
+void foo(int* p) {
+  if (p == nullptr)
+"__llvm_verbose_trap: Argument_must_not_be_null"();
+}
+
+However, the LLVM IR would not actually contain a call to the artificial
+function — it only exists in the debug metadata.
+
+Query for this feature with ``__has_builtin(__builtin_verbose_trap)``.
+
 ``__builtin_allow_runtime_check``
 -
 
@@ -3514,7 +3562,6 @@ guarded check. It's unused now. It will enable 
kind-specific lowering in future.
 E.g. a higher hotness cutoff can be used for more expensive kind of check.
 
 Query for this feature with ``__has_builtin(__builtin_allow_runtime_check)``.
-
 ``__builtin_nondeterministic_value``
 
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 2bfefeabc348b..9606a5fddd47e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,11 @@ class Expr : public ValueStmt {
  const Expr *PtrExpression, ASTContext &Ctx,
  EvalResult &Status) const;
 
+  /// If the current Expr can be evaluated to a pointer to a null-terminated
+  /// constant string, return the constant string (without the terminating 
null)
+  /// in Result. Return true if it succeeds.
+  bool tryEvaluateString(std::string &Result, ASTContext &Ctx) const;
+
   /// Enumeration used to describe the kind of Null pointer constant
   /// returned from \c isNullPointerConstant().
   enum NullPointerConstantKind {
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index de721a87b3341..5b3b9d04e576a 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1152,6 +1152,12 @@ def Trap : Builtin {
   let Prototype = "void()";
 }
 
+def VerboseTrap : Builtin {
+  let Spellings = ["__builtin_verbose_trap"];
+  let Attributes = [NoThrow, NoReturn];
+  let Prototype 

[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-24 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/79230

>From 95200f3bb3859738981240a9d8c503a13ede9601 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 16 Jan 2024 13:18:09 -0800
Subject: [PATCH 01/18] Add support for builtin_verbose_trap

The builtin causes the program to stop its execution abnormally and shows a
human-readable description of the reason for the termination when a debugger is
attached or in a symbolicated crash log.

The motivation for the builtin is explained in the following RFC:

https://discourse.llvm.org/t/rfc-adding-builtin-verbose-trap-string-literal/75845
---
 clang/docs/LanguageExtensions.rst | 49 ++-
 clang/include/clang/AST/Expr.h|  5 ++
 clang/include/clang/Basic/Builtins.td |  6 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/AST/ExprConstant.cpp| 18 +--
 clang/lib/CodeGen/CGBuiltin.cpp   | 12 +
 clang/lib/CodeGen/CGDebugInfo.cpp | 42 
 clang/lib/CodeGen/CGDebugInfo.h   | 20 
 clang/lib/Sema/SemaChecking.cpp   | 22 +
 .../CodeGenCXX/debug-info-verbose-trap.cpp| 49 +++
 clang/test/SemaCXX/verbose-trap.cpp   | 28 +++
 11 files changed, 249 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/debug-info-verbose-trap.cpp
 create mode 100644 clang/test/SemaCXX/verbose-trap.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 84fc4dee02fa8..1dd8d3bcec920 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3467,6 +3467,54 @@ Query for this feature with 
``__has_builtin(__builtin_trap)``.
 
 ``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and 
then to ``brk #payload``.
 
+``__builtin_verbose_trap``
+--
+
+``__builtin_verbose_trap`` causes the program to stop its execution abnormally
+and shows a human-readable description of the reason for the termination when a
+debugger is attached or in a symbolicated crash log.
+
+**Syntax**:
+
+.. code-block:: c++
+
+__builtin_verbose_trap(const char *reason)
+
+**Description**
+
+``__builtin_verbose_trap`` is lowered to the ` ``llvm.trap`` 
`_ builtin.
+Additionally, clang emits debug metadata that represents an artificial inline
+frame whose name encodes the string passed to the builtin, prefixed by a 
"magic"
+prefix.
+
+For example, consider the following code:
+
+.. code-block:: c++
+
+void foo(int* p) {
+  if (p == nullptr)
+__builtin_verbose_trap("Argument_must_not_be_null");
+}
+
+The debug metadata would look as if it were produced for the following code:
+
+.. code-block:: c++
+
+__attribute__((always_inline))
+inline void "__llvm_verbose_trap: Argument_must_not_be_null"() {
+  __builtin_trap();
+}
+
+void foo(int* p) {
+  if (p == nullptr)
+"__llvm_verbose_trap: Argument_must_not_be_null"();
+}
+
+However, the LLVM IR would not actually contain a call to the artificial
+function — it only exists in the debug metadata.
+
+Query for this feature with ``__has_builtin(__builtin_verbose_trap)``.
+
 ``__builtin_allow_runtime_check``
 -
 
@@ -3514,7 +3562,6 @@ guarded check. It's unused now. It will enable 
kind-specific lowering in future.
 E.g. a higher hotness cutoff can be used for more expensive kind of check.
 
 Query for this feature with ``__has_builtin(__builtin_allow_runtime_check)``.
-
 ``__builtin_nondeterministic_value``
 
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 2bfefeabc348b..9606a5fddd47e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,11 @@ class Expr : public ValueStmt {
  const Expr *PtrExpression, ASTContext &Ctx,
  EvalResult &Status) const;
 
+  /// If the current Expr can be evaluated to a pointer to a null-terminated
+  /// constant string, return the constant string (without the terminating 
null)
+  /// in Result. Return true if it succeeds.
+  bool tryEvaluateString(std::string &Result, ASTContext &Ctx) const;
+
   /// Enumeration used to describe the kind of Null pointer constant
   /// returned from \c isNullPointerConstant().
   enum NullPointerConstantKind {
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index de721a87b3341..5b3b9d04e576a 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1152,6 +1152,12 @@ def Trap : Builtin {
   let Prototype = "void()";
 }
 
+def VerboseTrap : Builtin {
+  let Spellings = ["__builtin_verbose_trap"];
+  let Attributes = [NoThrow, NoReturn];
+  let Prototype 

[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-21 Thread Akira Hatanaka via cfe-commits


@@ -27,6 +27,9 @@ namespace llvm {
   }
 }
 
+// Prefix for __builtin_verbose_trap.
+#define CLANG_VERBOSE_TRAP_PREFIX "__llvm_verbose_trap"

ahatanak wrote:

I don't have any preference, but according to people working on lldb, macro 
would make it marginally easier to construct the regex in the LLDB frame 
recognizer.

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


[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-21 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/79230

>From 95200f3bb3859738981240a9d8c503a13ede9601 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 16 Jan 2024 13:18:09 -0800
Subject: [PATCH 01/17] Add support for builtin_verbose_trap

The builtin causes the program to stop its execution abnormally and shows a
human-readable description of the reason for the termination when a debugger is
attached or in a symbolicated crash log.

The motivation for the builtin is explained in the following RFC:

https://discourse.llvm.org/t/rfc-adding-builtin-verbose-trap-string-literal/75845
---
 clang/docs/LanguageExtensions.rst | 49 ++-
 clang/include/clang/AST/Expr.h|  5 ++
 clang/include/clang/Basic/Builtins.td |  6 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/AST/ExprConstant.cpp| 18 +--
 clang/lib/CodeGen/CGBuiltin.cpp   | 12 +
 clang/lib/CodeGen/CGDebugInfo.cpp | 42 
 clang/lib/CodeGen/CGDebugInfo.h   | 20 
 clang/lib/Sema/SemaChecking.cpp   | 22 +
 .../CodeGenCXX/debug-info-verbose-trap.cpp| 49 +++
 clang/test/SemaCXX/verbose-trap.cpp   | 28 +++
 11 files changed, 249 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/debug-info-verbose-trap.cpp
 create mode 100644 clang/test/SemaCXX/verbose-trap.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 84fc4dee02fa8..1dd8d3bcec920 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3467,6 +3467,54 @@ Query for this feature with 
``__has_builtin(__builtin_trap)``.
 
 ``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and 
then to ``brk #payload``.
 
+``__builtin_verbose_trap``
+--
+
+``__builtin_verbose_trap`` causes the program to stop its execution abnormally
+and shows a human-readable description of the reason for the termination when a
+debugger is attached or in a symbolicated crash log.
+
+**Syntax**:
+
+.. code-block:: c++
+
+__builtin_verbose_trap(const char *reason)
+
+**Description**
+
+``__builtin_verbose_trap`` is lowered to the ` ``llvm.trap`` 
`_ builtin.
+Additionally, clang emits debug metadata that represents an artificial inline
+frame whose name encodes the string passed to the builtin, prefixed by a 
"magic"
+prefix.
+
+For example, consider the following code:
+
+.. code-block:: c++
+
+void foo(int* p) {
+  if (p == nullptr)
+__builtin_verbose_trap("Argument_must_not_be_null");
+}
+
+The debug metadata would look as if it were produced for the following code:
+
+.. code-block:: c++
+
+__attribute__((always_inline))
+inline void "__llvm_verbose_trap: Argument_must_not_be_null"() {
+  __builtin_trap();
+}
+
+void foo(int* p) {
+  if (p == nullptr)
+"__llvm_verbose_trap: Argument_must_not_be_null"();
+}
+
+However, the LLVM IR would not actually contain a call to the artificial
+function — it only exists in the debug metadata.
+
+Query for this feature with ``__has_builtin(__builtin_verbose_trap)``.
+
 ``__builtin_allow_runtime_check``
 -
 
@@ -3514,7 +3562,6 @@ guarded check. It's unused now. It will enable 
kind-specific lowering in future.
 E.g. a higher hotness cutoff can be used for more expensive kind of check.
 
 Query for this feature with ``__has_builtin(__builtin_allow_runtime_check)``.
-
 ``__builtin_nondeterministic_value``
 
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 2bfefeabc348b..9606a5fddd47e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,11 @@ class Expr : public ValueStmt {
  const Expr *PtrExpression, ASTContext &Ctx,
  EvalResult &Status) const;
 
+  /// If the current Expr can be evaluated to a pointer to a null-terminated
+  /// constant string, return the constant string (without the terminating 
null)
+  /// in Result. Return true if it succeeds.
+  bool tryEvaluateString(std::string &Result, ASTContext &Ctx) const;
+
   /// Enumeration used to describe the kind of Null pointer constant
   /// returned from \c isNullPointerConstant().
   enum NullPointerConstantKind {
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index de721a87b3341..5b3b9d04e576a 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1152,6 +1152,12 @@ def Trap : Builtin {
   let Prototype = "void()";
 }
 
+def VerboseTrap : Builtin {
+  let Spellings = ["__builtin_verbose_trap"];
+  let Attributes = [NoThrow, NoReturn];
+  let Prototype 

[clang] Add support for builtin_verbose_trap (PR #79230)

2024-06-21 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

> I think my last comment/question is still open? How/why did the symbol name 
> end up dropping any llvm/clang component to avoid collisions with other names?

I dropped llvm/clang because I didn't think it would cause any collision in 
practice, but I don't think we have to try too hard to shorten the prefix.

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


[clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)

2024-06-21 Thread Akira Hatanaka via cfe-commits

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


[clang] Check whether EvaluatedStmt::Value is valid in VarDecl::hasInit (PR #94515)

2024-06-14 Thread Akira Hatanaka via cfe-commits

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


[clang] Check whether EvaluatedStmt::Value is valid in VarDecl::hasInit (PR #94515)

2024-06-13 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/94515

>From 22a8fa09e81337f45c2ed94e229f06e9aaa32c0e Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 5 Jun 2024 11:02:31 -0700
Subject: [PATCH 1/2] Check whether EvaluatedStmt::Value is valid in
 VarDecl::hasInit

VarDecl::isNull() doesn't tell whether the VarDecl has an initializer as
methods like ensureEvaluatedStmt can create an EvaluatedStmt even when
there isn't an initializer.

Revert e1c3e16d24b5cc097ff08e9283f53319acd3f245 as the change isn't
needed anymore with this change.

See the discussion in https://github.com/llvm/llvm-project/pull/93749.
---
 clang/lib/AST/Decl.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 1f19dadafa44e..fc04f877b2268 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2390,6 +2390,9 @@ bool VarDecl::hasInit() const {
 if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg())
   return false;
 
+  if (auto *Eval = getEvaluatedStmt())
+return Eval->Value.isValid();
+
   return !Init.isNull();
 }
 
@@ -2402,10 +2405,9 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_if_present(
-  Eval->Value.isOffset()
-  ? Eval->Value.get(getASTContext().getExternalSource())
-  : Eval->Value.get(nullptr));
+  return cast(Eval->Value.isOffset()
+? Eval->Value.get(getASTContext().getExternalSource())
+: Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {

>From a54e9ac892aa7bbbcf73256e7ac5eaec187578fe Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 13 Jun 2024 18:21:38 -0700
Subject: [PATCH 2/2] Move the conditional into the argument

---
 clang/lib/AST/Decl.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index fc04f877b2268..9d0a835a12c45 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2405,9 +2405,8 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast(Eval->Value.isOffset()
-? Eval->Value.get(getASTContext().getExternalSource())
-: Eval->Value.get(nullptr));
+  return cast(Eval->Value.get(
+  Eval->Value.isOffset() ? getASTContext().getExternalSource() : nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {

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


[clang] [llvm] [CodeGen][arm64e] Add methods and data members to Address, which are needed to authenticate signed pointers (PR #86923)

2024-06-13 Thread Akira Hatanaka via cfe-commits


@@ -201,14 +211,26 @@ template <> struct DominatingValue {
   class saved_type {
 enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
 AggregateAddress, ComplexAddress };
-
-llvm::Value *Value;
-llvm::Type *ElementType;
+union {
+  struct {
+DominatingLLVMValue::saved_type first, second;
+  } Vals;
+  DominatingValue::saved_type AggregateAddr;
+};
 LLVM_PREFERRED_TYPE(Kind)
 unsigned K : 3;
-unsigned Align : 29;
-saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0)
-  : Value(v), ElementType(e), K(k), Align(a) {}
+unsigned IsVolatile : 1;

ahatanak wrote:

Fixed in https://github.com/llvm/llvm-project/pull/95165

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


[clang] [CodeGen] Remove IsVolatile from DominatingValue::save_type (PR #95165)

2024-06-12 Thread Akira Hatanaka via cfe-commits

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


[clang] [CodeGen] Remove IsVolatile from DominatingValue::save_type (PR #95165)

2024-06-11 Thread Akira Hatanaka via cfe-commits

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


[clang] [CodeGen] Remove IsVolatile from DominatingValue::save_type (PR #95165)

2024-06-11 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/95165

Prior to 84780af4b02cb3b86e4cb724f996bf8e02f2f2e7, the class didn't have any 
information about whether the saved value was volatile.

This is NFC as far as I can tell.

>From 09faa416eb234ab3bf8e1babb3a7c206968eecc5 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Fri, 7 Jun 2024 22:08:38 -0700
Subject: [PATCH] [CodeGen] Remove IsVolatile from
 DominatingValue::save_type

Prior to 84780af4b02cb3b86e4cb724f996bf8e02f2f2e7, the class didn't have
any information about whether the saved value was volatile.

This is NFC as far as I can tell.
---
 clang/lib/CodeGen/CGCleanup.cpp | 10 +-
 clang/lib/CodeGen/CodeGenFunction.h |  4 +---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index 469e0363b744a..4e210a9e3c95f 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -48,10 +48,10 @@ DominatingValue::saved_type::save(CodeGenFunction 
&CGF, RValue rv) {
 
   assert(rv.isAggregate());
   Address V = rv.getAggregateAddress();
-  return saved_type(
-  DominatingValue::save(CGF, V), rv.isVolatileQualified(),
-  DominatingValue::needsSaving(V) ? AggregateAddress
-   : AggregateLiteral);
+  return saved_type(DominatingValue::save(CGF, V),
+DominatingValue::needsSaving(V)
+? AggregateAddress
+: AggregateLiteral);
 }
 
 /// Given a saved r-value produced by SaveRValue, perform the code
@@ -65,7 +65,7 @@ RValue 
DominatingValue::saved_type::restore(CodeGenFunction &CGF) {
   case AggregateLiteral:
   case AggregateAddress:
 return RValue::getAggregate(
-DominatingValue::restore(CGF, AggregateAddr), IsVolatile);
+DominatingValue::restore(CGF, AggregateAddr));
   case ComplexAddress: {
 llvm::Value *real = DominatingLLVMValue::restore(CGF, Vals.first);
 llvm::Value *imag = DominatingLLVMValue::restore(CGF, Vals.second);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 5739fbaaa9194..06fc7259b5901 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -221,7 +221,6 @@ template <> struct DominatingValue {
 };
 LLVM_PREFERRED_TYPE(Kind)
 unsigned K : 3;
-unsigned IsVolatile : 1;
 
 saved_type(DominatingLLVMValue::saved_type Val1, unsigned K)
 : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {}
@@ -230,8 +229,7 @@ template <> struct DominatingValue {
DominatingLLVMValue::saved_type Val2)
 : Vals{Val1, Val2}, K(ComplexAddress) {}
 
-saved_type(DominatingValue::saved_type AggregateAddr,
-   bool IsVolatile, unsigned K)
+saved_type(DominatingValue::saved_type AggregateAddr, unsigned K)
 : AggregateAddr(AggregateAddr), K(K) {}
 
   public:

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


[clang] [llvm] [CodeGen][arm64e] Add methods and data members to Address, which are needed to authenticate signed pointers (PR #86923)

2024-06-07 Thread Akira Hatanaka via cfe-commits


@@ -201,14 +211,26 @@ template <> struct DominatingValue {
   class saved_type {
 enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
 AggregateAddress, ComplexAddress };
-
-llvm::Value *Value;
-llvm::Type *ElementType;
+union {
+  struct {
+DominatingLLVMValue::saved_type first, second;
+  } Vals;
+  DominatingValue::saved_type AggregateAddr;
+};
 LLVM_PREFERRED_TYPE(Kind)
 unsigned K : 3;
-unsigned Align : 29;
-saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0)
-  : Value(v), ElementType(e), K(k), Align(a) {}
+unsigned IsVolatile : 1;

ahatanak wrote:

CC @rjmccall

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


[clang] [llvm] [CodeGen][arm64e] Add methods and data members to Address, which are needed to authenticate signed pointers (PR #86923)

2024-06-07 Thread Akira Hatanaka via cfe-commits


@@ -201,14 +211,26 @@ template <> struct DominatingValue {
   class saved_type {
 enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
 AggregateAddress, ComplexAddress };
-
-llvm::Value *Value;
-llvm::Type *ElementType;
+union {
+  struct {
+DominatingLLVMValue::saved_type first, second;
+  } Vals;
+  DominatingValue::saved_type AggregateAddr;
+};
 LLVM_PREFERRED_TYPE(Kind)
 unsigned K : 3;
-unsigned Align : 29;
-saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0)
-  : Value(v), ElementType(e), K(k), Align(a) {}
+unsigned IsVolatile : 1;

ahatanak wrote:

Prior to this commit, `DominatingValue` didn't have any information 
about whether the saved `RValue` was volatile. I don't think we need that 
information.

`IsVolatile` should be removed. 

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


[clang] Fix spurious non-strict availability warning (PR #94377)

2024-06-06 Thread Akira Hatanaka via cfe-commits

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


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


[clang] Check whether EvaluatedStmt::Value is valid in VarDecl::hasInit (PR #94515)

2024-06-05 Thread Akira Hatanaka via cfe-commits

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


[clang] Check whether EvaluatedStmt::Value is valid in VarDecl::hasInit (PR #94515)

2024-06-05 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/94515

>From 22a8fa09e81337f45c2ed94e229f06e9aaa32c0e Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 5 Jun 2024 11:02:31 -0700
Subject: [PATCH] Check whether EvaluatedStmt::Value is valid in
 VarDecl::hasInit

VarDecl::isNull() doesn't tell whether the VarDecl has an initializer as
methods like ensureEvaluatedStmt can create an EvaluatedStmt even when
there isn't an initializer.

Revert e1c3e16d24b5cc097ff08e9283f53319acd3f245 as the change isn't
needed anymore with this change.

See the discussion in https://github.com/llvm/llvm-project/pull/93749.
---
 clang/lib/AST/Decl.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 1f19dadafa44e..fc04f877b2268 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2390,6 +2390,9 @@ bool VarDecl::hasInit() const {
 if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg())
   return false;
 
+  if (auto *Eval = getEvaluatedStmt())
+return Eval->Value.isValid();
+
   return !Init.isNull();
 }
 
@@ -2402,10 +2405,9 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_if_present(
-  Eval->Value.isOffset()
-  ? Eval->Value.get(getASTContext().getExternalSource())
-  : Eval->Value.get(nullptr));
+  return cast(Eval->Value.isOffset()
+? Eval->Value.get(getASTContext().getExternalSource())
+: Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {

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


[clang] Check whether EvaluatedStmt::Value is valid in VarDecl::hasInit (PR #94515)

2024-06-05 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/94515

VarDecl::isNull() doesn't tell whether the VarDecl has an initializer as 
methods like ensureEvaluatedStmt can create an EvaluatedStmt even when there 
isn't an initializer.

Revert e1c3e16d24b5cc097ff08e9283f53319acd3f245 as the change isn't needed 
anymore with this change.

See the discussion in https://github.com/llvm/llvm-project/pull/93749.

>From 91751f09a1ca73f75c892c89ef7c312ad4df2c64 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 5 Jun 2024 11:02:31 -0700
Subject: [PATCH] Check whether EvaluatedStmt::Value is valid in
 VarDecl::hasInit

VarDecl::isNull() doesn't tell whether the VarDecl has an initializer as
methods like ensureEvaluatedStmt can create an EvaluatedStmt even when
there isn't an initializer.

Revert e1c3e16d24b5cc097ff08e9283f53319acd3f245 as the change isn't
needed anymore with this change.

See the discussion in https://github.com/llvm/llvm-project/pull/93749.
---
 clang/lib/AST/Decl.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 1f19dadafa44e..fc04f877b2268 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2390,6 +2390,9 @@ bool VarDecl::hasInit() const {
 if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg())
   return false;
 
+  if (auto *Eval = getEvaluatedStmt())
+return Eval->Value.isValid();
+
   return !Init.isNull();
 }
 
@@ -2402,10 +2405,9 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_if_present(
-  Eval->Value.isOffset()
-  ? Eval->Value.get(getASTContext().getExternalSource())
-  : Eval->Value.get(nullptr));
+  return cast(Eval->Value.isOffset()
+? Eval->Value.get(getASTContext().getExternalSource())
+: Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {

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


[clang] [clang] Add arm64e ABI-defined key assignments to ptrauth.h. (PR #93901)

2024-05-30 Thread Akira Hatanaka via cfe-commits

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


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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

I can see if we can make `hasInit` check that too or rename the function after 
committing this patch.

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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

`hasInit` checks whether `VarDecl::Init`'s pointer is null. But 
`VarDecl::ensureEvaluatedStmt` creates an `EvaluatedStmt` if there isn't one 
already,  after which `hasInit` returns true.

https://github.com/llvm/llvm-project/blob/3af717d661e9fe8d562181b933a373ca58e41b27/clang/lib/AST/Decl.cpp#L2541

`Init.get()` returns null when there's no initializer.

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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/93749

>From 4648f46f5e15d5747596347feaef85069a8ce4df Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 29 May 2024 15:19:58 -0700
Subject: [PATCH 1/3] Use cast_or_null instead of cast

`Eval->Value.get` returns a null pointer when the variable doesn't have
an initializer.

This fixes https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541
---
 clang/lib/AST/Decl.cpp |  8 +---
 clang/test/SemaObjCXX/block-capture.mm | 18 ++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 41fbfe281ef65..4940a787e7d30 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() {
 return cast(S);
 
   auto *Eval = getEvaluatedStmt();
-  return cast(Eval->Value.isOffset()
-? Eval->Value.get(getASTContext().getExternalSource())
-: Eval->Value.get(nullptr));
+
+  return cast_or_null(
+  Eval->Value.isOffset()
+  ? Eval->Value.get(getASTContext().getExternalSource())
+  : Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {
diff --git a/clang/test/SemaObjCXX/block-capture.mm 
b/clang/test/SemaObjCXX/block-capture.mm
index 8ba02f919e015..231aef33f2c7e 100644
--- a/clang/test/SemaObjCXX/block-capture.mm
+++ b/clang/test/SemaObjCXX/block-capture.mm
@@ -83,3 +83,21 @@
   SubMove(SubSubMove &&);
 };
 TEST(SubMove);
+
+
+#if __cplusplus >= 202302L
+// clang used to crash compiling this code.
+namespace BlockInLambda {
+  struct S {
+constexpr ~S();
+  };
+
+  void func(S const &a) {
+[a](auto b) {
+  ^{
+(void)a;
+  }();
+}(12);
+  }
+}
+#endif

>From de2bd511b5dcd683b762b7bc68f8628de30f3341 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 30 May 2024 09:12:49 -0700
Subject: [PATCH 2/3] Use cast_if_present

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

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4940a787e7d30..0a35ed536a6a7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2409,7 +2409,7 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_or_null(
+  return cast_if_present(
   Eval->Value.isOffset()
   ? Eval->Value.get(getASTContext().getExternalSource())
   : Eval->Value.get(nullptr));

>From 23908d596741b271feb70feb6291bc5b8a5ed97b Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 30 May 2024 10:06:47 -0700
Subject: [PATCH 3/3] Add an entry in release note

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 44035f48cb3f9..0d9e4b8aba500 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -813,6 +813,7 @@ Bug Fixes to C++ Support
 - Clang now allows ``@$``` in raw string literals. Fixes (#GH93130).
 - Fix an assertion failure when checking invalid ``this`` usage in the wrong 
context. (Fixes #GH91536).
 - Clang no longer models dependent NTTP arguments as 
``TemplateParamObjectDecl`` s. Fixes (#GH84052).
+- Fix a crash when a variable is captured by a block nested inside a lambda. 
(Fixes #GH93625).
 
 Bug Fixes to AST Handling
 ^

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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/93749

>From 4648f46f5e15d5747596347feaef85069a8ce4df Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 29 May 2024 15:19:58 -0700
Subject: [PATCH 1/3] Use cast_or_null instead of cast

`Eval->Value.get` returns a null pointer when the variable doesn't have
an initializer.

This fixes https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541
---
 clang/lib/AST/Decl.cpp |  8 +---
 clang/test/SemaObjCXX/block-capture.mm | 18 ++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 41fbfe281ef65..4940a787e7d30 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() {
 return cast(S);
 
   auto *Eval = getEvaluatedStmt();
-  return cast(Eval->Value.isOffset()
-? Eval->Value.get(getASTContext().getExternalSource())
-: Eval->Value.get(nullptr));
+
+  return cast_or_null(
+  Eval->Value.isOffset()
+  ? Eval->Value.get(getASTContext().getExternalSource())
+  : Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {
diff --git a/clang/test/SemaObjCXX/block-capture.mm 
b/clang/test/SemaObjCXX/block-capture.mm
index 8ba02f919e015..231aef33f2c7e 100644
--- a/clang/test/SemaObjCXX/block-capture.mm
+++ b/clang/test/SemaObjCXX/block-capture.mm
@@ -83,3 +83,21 @@
   SubMove(SubSubMove &&);
 };
 TEST(SubMove);
+
+
+#if __cplusplus >= 202302L
+// clang used to crash compiling this code.
+namespace BlockInLambda {
+  struct S {
+constexpr ~S();
+  };
+
+  void func(S const &a) {
+[a](auto b) {
+  ^{
+(void)a;
+  }();
+}(12);
+  }
+}
+#endif

>From de2bd511b5dcd683b762b7bc68f8628de30f3341 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 30 May 2024 09:12:49 -0700
Subject: [PATCH 2/3] Use cast_if_present

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

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4940a787e7d30..0a35ed536a6a7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2409,7 +2409,7 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_or_null(
+  return cast_if_present(
   Eval->Value.isOffset()
   ? Eval->Value.get(getASTContext().getExternalSource())
   : Eval->Value.get(nullptr));

>From 23908d596741b271feb70feb6291bc5b8a5ed97b Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 30 May 2024 10:06:47 -0700
Subject: [PATCH 3/3] Add an entry in release note

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 44035f48cb3f9..0d9e4b8aba500 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -813,6 +813,7 @@ Bug Fixes to C++ Support
 - Clang now allows ``@$``` in raw string literals. Fixes (#GH93130).
 - Fix an assertion failure when checking invalid ``this`` usage in the wrong 
context. (Fixes #GH91536).
 - Clang no longer models dependent NTTP arguments as 
``TemplateParamObjectDecl`` s. Fixes (#GH84052).
+- Fix a crash when a variable is captured by a block nested inside a lambda. 
(Fixes #GH93625).
 
 Bug Fixes to AST Handling
 ^

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


[clang] [clang] Fix a crash when a variable is captured by a block nested inside a lambda (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

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


[clang] Use cast_or_null instead of cast (PR #93749)

2024-05-30 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/93749

>From 4648f46f5e15d5747596347feaef85069a8ce4df Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 29 May 2024 15:19:58 -0700
Subject: [PATCH 1/2] Use cast_or_null instead of cast

`Eval->Value.get` returns a null pointer when the variable doesn't have
an initializer.

This fixes https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541
---
 clang/lib/AST/Decl.cpp |  8 +---
 clang/test/SemaObjCXX/block-capture.mm | 18 ++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 41fbfe281ef65..4940a787e7d30 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() {
 return cast(S);
 
   auto *Eval = getEvaluatedStmt();
-  return cast(Eval->Value.isOffset()
-? Eval->Value.get(getASTContext().getExternalSource())
-: Eval->Value.get(nullptr));
+
+  return cast_or_null(
+  Eval->Value.isOffset()
+  ? Eval->Value.get(getASTContext().getExternalSource())
+  : Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {
diff --git a/clang/test/SemaObjCXX/block-capture.mm 
b/clang/test/SemaObjCXX/block-capture.mm
index 8ba02f919e015..231aef33f2c7e 100644
--- a/clang/test/SemaObjCXX/block-capture.mm
+++ b/clang/test/SemaObjCXX/block-capture.mm
@@ -83,3 +83,21 @@
   SubMove(SubSubMove &&);
 };
 TEST(SubMove);
+
+
+#if __cplusplus >= 202302L
+// clang used to crash compiling this code.
+namespace BlockInLambda {
+  struct S {
+constexpr ~S();
+  };
+
+  void func(S const &a) {
+[a](auto b) {
+  ^{
+(void)a;
+  }();
+}(12);
+  }
+}
+#endif

>From de2bd511b5dcd683b762b7bc68f8628de30f3341 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Thu, 30 May 2024 09:12:49 -0700
Subject: [PATCH 2/2] Use cast_if_present

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

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 4940a787e7d30..0a35ed536a6a7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2409,7 +2409,7 @@ Expr *VarDecl::getInit() {
 
   auto *Eval = getEvaluatedStmt();
 
-  return cast_or_null(
+  return cast_if_present(
   Eval->Value.isOffset()
   ? Eval->Value.get(getASTContext().getExternalSource())
   : Eval->Value.get(nullptr));

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


[clang] Use cast_or_null instead of cast (PR #93749)

2024-05-29 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

Note that the call to `hasInit` at the beginning of function `VarDecl::getInit` 
returns true even when the variable doesn't have an initializer if 
`VarDecl::ensureEvaluatedStmt` is called before that.

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


[clang] Use cast_or_null instead of cast (PR #93749)

2024-05-29 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak created 
https://github.com/llvm/llvm-project/pull/93749

`Eval->Value.get` returns a null pointer when the variable doesn't have an 
initializer.

This fixes https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541

>From 4648f46f5e15d5747596347feaef85069a8ce4df Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 29 May 2024 15:19:58 -0700
Subject: [PATCH] Use cast_or_null instead of cast

`Eval->Value.get` returns a null pointer when the variable doesn't have
an initializer.

This fixes https://github.com/llvm/llvm-project/issues/93625.

rdar://128482541
---
 clang/lib/AST/Decl.cpp |  8 +---
 clang/test/SemaObjCXX/block-capture.mm | 18 ++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 41fbfe281ef65..4940a787e7d30 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() {
 return cast(S);
 
   auto *Eval = getEvaluatedStmt();
-  return cast(Eval->Value.isOffset()
-? Eval->Value.get(getASTContext().getExternalSource())
-: Eval->Value.get(nullptr));
+
+  return cast_or_null(
+  Eval->Value.isOffset()
+  ? Eval->Value.get(getASTContext().getExternalSource())
+  : Eval->Value.get(nullptr));
 }
 
 Stmt **VarDecl::getInitAddress() {
diff --git a/clang/test/SemaObjCXX/block-capture.mm 
b/clang/test/SemaObjCXX/block-capture.mm
index 8ba02f919e015..231aef33f2c7e 100644
--- a/clang/test/SemaObjCXX/block-capture.mm
+++ b/clang/test/SemaObjCXX/block-capture.mm
@@ -83,3 +83,21 @@
   SubMove(SubSubMove &&);
 };
 TEST(SubMove);
+
+
+#if __cplusplus >= 202302L
+// clang used to crash compiling this code.
+namespace BlockInLambda {
+  struct S {
+constexpr ~S();
+  };
+
+  void func(S const &a) {
+[a](auto b) {
+  ^{
+(void)a;
+  }();
+}(12);
+  }
+}
+#endif

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


[clang] [clang][CodeGen] Remove unused LValue::getAddress CGF arg. (PR #92465)

2024-05-16 Thread Akira Hatanaka via cfe-commits

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


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


[clang] Add support for builtin_verbose_trap (PR #79230)

2024-05-10 Thread Akira Hatanaka via cfe-commits


@@ -172,6 +172,27 @@ static bool checkArgCount(Sema &S, CallExpr *Call, 
unsigned DesiredArgCount) {
  << /*is non object*/ 0 << Call->getArg(1)->getSourceRange();
 }
 
+static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S) {

ahatanak wrote:

clang already checks that the number of arguments is exactly 2 (see 
`test/SemaCXX/verbose-trap.cpp`).

I agree that we should check that `$` isn't in the strings.

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


[clang] Add support for builtin_verbose_trap (PR #79230)

2024-05-09 Thread Akira Hatanaka via cfe-commits


@@ -27,6 +27,9 @@ namespace llvm {
   }
 }
 
+// Prefix for __builtin_verbose_trap.
+#define CLANG_VERBOSE_TRAP_PREFIX "__llvm_verbose_trap"

ahatanak wrote:

I can make it a C++ constant if that's preferable.

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


[clang] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification (PR #85886)

2024-05-09 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/85886

>From d39667c7e65c10babb478d8f8d54fecb66d90568 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 19 Mar 2024 15:50:00 -0700
Subject: [PATCH 1/4] [Sema] Don't drop weak_import from a declaration that
 follows a declaration directly contained in a linkage-specification

Only drop it if the declaration follows a definition. I believe this is
what 33e022650adee965c65f9aea086ee74f3fd1bad5 was trying to do.

rdar://61865848
---
 clang/lib/Sema/SemaDecl.cpp  | 3 +--
 clang/test/SemaCXX/attr-weak.cpp | 7 +++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9..2e45f1191273 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,8 +4613,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() &&
-  Old->getStorageClass() == SC_None &&
+  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
   !Old->hasAttr()) {
 Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
 Diag(Old->getLocation(), diag::note_previous_declaration);
diff --git a/clang/test/SemaCXX/attr-weak.cpp b/clang/test/SemaCXX/attr-weak.cpp
index f065bfd9483f..a2c5fd4abd35 100644
--- a/clang/test/SemaCXX/attr-weak.cpp
+++ b/clang/test/SemaCXX/attr-weak.cpp
@@ -55,3 +55,10 @@ constexpr bool weak_method_is_non_null = 
&WithWeakMember::weak_method != nullptr
 // virtual member function is present.
 constexpr bool virtual_weak_method_is_non_null = 
&WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be 
initialized by a constant expression}}
 // expected-note@-1 {{comparison against pointer to weak member 
'WithWeakMember::virtual_weak_method' can only be performed at runtime}}
+
+// Check that no warnings are emitted.
+extern "C" int g0;
+extern int g0 __attribute__((weak_import));
+
+extern "C" int g1 = 0; // expected-note {{previous definition is here}}
+extern int g1 __attribute__((weak_import)); // expected-warning {{attribute 
declaration must precede definition}}

>From 33e3219c721d0c03f445c9bb977cb9f3809e74ac Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 8 May 2024 20:40:58 -0700
Subject: [PATCH 2/4] Check whether there's a definition at all

---
 clang/lib/Sema/SemaDecl.cpp | 23 +--
 clang/test/Sema/attr-weak.c |  4 
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2e45f1191273..0be6906026a8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,12 +4613,23 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
-  !Old->hasAttr()) {
-Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
-Diag(Old->getLocation(), diag::note_previous_declaration);
-// Remove weak_import attribute on new declaration.
-New->dropAttr();
+  if (New->hasAttr()) {
+// We know there's no full definition as the attribute on New would have
+// been removed otherwise. Just look for the most recent tentative
+// definition.
+VarDecl *TentativeDef = nullptr;
+for (auto *D = Old; D; D = D->getPreviousDecl())
+  if (D->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) {
+TentativeDef = D;
+break;
+  }
+
+if (TentativeDef) {
+  Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
+  Diag(TentativeDef->getLocation(), diag::note_previous_declaration);
+  // Remove weak_import attribute on new declaration.
+  New->dropAttr();
+}
   }
 
   if (const auto *ILA = New->getAttr())
diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c
index b827d1539b99..94e1723e125b 100644
--- a/clang/test/Sema/attr-weak.c
+++ b/clang/test/Sema/attr-weak.c
@@ -19,6 +19,10 @@ static int x __attribute__((weak)); // expected-error {{weak 
declaration cannot
 int C; // expected-note {{previous declaration is here}}
 extern int C __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
 
+int C2; // expected-note {{previous declaration is here}}
+extern int C2;
+extern int C2 __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
+
 static int pr14946_x;
 extern int pr14946_x  __attribute__((weak)); // expected-error {{weak 
declaration cannot have internal linkage}}
 

>From c33375cbc8863be911f7832538228cfde0e1d58d Mon Sep 17 00:00:00 2001
Fro

[clang] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification (PR #85886)

2024-05-09 Thread Akira Hatanaka via cfe-commits

ahatanak wrote:

The updated patch checks that the decl isn't `DeclarationOnly` to make it clear 
that we are looking for all definitions although we know we won't find any full 
definitions.

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


[clang] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification (PR #85886)

2024-05-09 Thread Akira Hatanaka via cfe-commits

https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/85886

>From d39667c7e65c10babb478d8f8d54fecb66d90568 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Tue, 19 Mar 2024 15:50:00 -0700
Subject: [PATCH 1/3] [Sema] Don't drop weak_import from a declaration that
 follows a declaration directly contained in a linkage-specification

Only drop it if the declaration follows a definition. I believe this is
what 33e022650adee965c65f9aea086ee74f3fd1bad5 was trying to do.

rdar://61865848
---
 clang/lib/Sema/SemaDecl.cpp  | 3 +--
 clang/test/SemaCXX/attr-weak.cpp | 7 +++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5850cd0ab6b9a..2e45f1191273a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,8 +4613,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() &&
-  Old->getStorageClass() == SC_None &&
+  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
   !Old->hasAttr()) {
 Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
 Diag(Old->getLocation(), diag::note_previous_declaration);
diff --git a/clang/test/SemaCXX/attr-weak.cpp b/clang/test/SemaCXX/attr-weak.cpp
index f065bfd9483f8..a2c5fd4abd35f 100644
--- a/clang/test/SemaCXX/attr-weak.cpp
+++ b/clang/test/SemaCXX/attr-weak.cpp
@@ -55,3 +55,10 @@ constexpr bool weak_method_is_non_null = 
&WithWeakMember::weak_method != nullptr
 // virtual member function is present.
 constexpr bool virtual_weak_method_is_non_null = 
&WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be 
initialized by a constant expression}}
 // expected-note@-1 {{comparison against pointer to weak member 
'WithWeakMember::virtual_weak_method' can only be performed at runtime}}
+
+// Check that no warnings are emitted.
+extern "C" int g0;
+extern int g0 __attribute__((weak_import));
+
+extern "C" int g1 = 0; // expected-note {{previous definition is here}}
+extern int g1 __attribute__((weak_import)); // expected-warning {{attribute 
declaration must precede definition}}

>From 33e3219c721d0c03f445c9bb977cb9f3809e74ac Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Wed, 8 May 2024 20:40:58 -0700
Subject: [PATCH 2/3] Check whether there's a definition at all

---
 clang/lib/Sema/SemaDecl.cpp | 23 +--
 clang/test/Sema/attr-weak.c |  4 
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2e45f1191273a..0be6906026a85 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4613,12 +4613,23 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult 
&Previous) {
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent
   // declaration
-  if (New->hasAttr() && Old->isThisDeclarationADefinition() &&
-  !Old->hasAttr()) {
-Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
-Diag(Old->getLocation(), diag::note_previous_declaration);
-// Remove weak_import attribute on new declaration.
-New->dropAttr();
+  if (New->hasAttr()) {
+// We know there's no full definition as the attribute on New would have
+// been removed otherwise. Just look for the most recent tentative
+// definition.
+VarDecl *TentativeDef = nullptr;
+for (auto *D = Old; D; D = D->getPreviousDecl())
+  if (D->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) {
+TentativeDef = D;
+break;
+  }
+
+if (TentativeDef) {
+  Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
+  Diag(TentativeDef->getLocation(), diag::note_previous_declaration);
+  // Remove weak_import attribute on new declaration.
+  New->dropAttr();
+}
   }
 
   if (const auto *ILA = New->getAttr())
diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c
index b827d1539b997..94e1723e125b6 100644
--- a/clang/test/Sema/attr-weak.c
+++ b/clang/test/Sema/attr-weak.c
@@ -19,6 +19,10 @@ static int x __attribute__((weak)); // expected-error {{weak 
declaration cannot
 int C; // expected-note {{previous declaration is here}}
 extern int C __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
 
+int C2; // expected-note {{previous declaration is here}}
+extern int C2;
+extern int C2 __attribute__((weak_import)); // expected-warning {{an 
already-declared variable is made a weak_import declaration}}
+
 static int pr14946_x;
 extern int pr14946_x  __attribute__((weak)); // expected-error {{weak 
declaration cannot have internal linkage}}
 

>From c33375cbc8863be911f7832538228cfde0e1d58d Mon Sep 17 00:00:00 

  1   2   3   4   5   6   7   8   9   10   >