Skip to content

[PAC] Ignore noexcept on function type when computing discriminator of member function pointers #109056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2025

Conversation

ahatanak
Copy link
Collaborator

Fixes #106487.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Sep 17, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 17, 2024

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Akira Hatanaka (ahatanak)

Changes

Fixes #106487.


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

3 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-2)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+22-6)
  • (modified) clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp (+107-2)
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<Expr*>(E));
 
   case CK_NoOp: {
-    return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
-                                              : Visit(const_cast<Expr *>(E));
+    if (CE->changesVolatileQualification())
+      return EmitLoadOfLValue(CE);
+    auto V = Visit(const_cast<Expr *>(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<llvm::Constant>(src))
     return EmitMemberPointerConversion(E, cast<llvm::Constant>(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/CodeGenCXX/ptrauth-member-function-pointer.cpp
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN %s
+// RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN,CXX11 %s
+// RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++17 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,DARWIN,CXX17 %s
 // RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,DARWIN %s
 // RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT
 // RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT
 // RUN: %clang_cc1 -triple arm64-apple-ios   -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT
 
-// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF,CXX11 %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++17 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG,ELF,CXX17 %s
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK,ELF %s
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT
@@ -20,6 +22,11 @@
 // CHECK: @__const._Z13testArrayInitv.c0 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 } }, align 8
 // CHECK: @__const._Z13testArrayInitv.c1 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 } }, align 8
 
+// CHECK: @_ZN22testNoexceptConversion6mfptr1E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[DISC_NO_NOEXCEPT:.*]]) to i64), i64 0 },
+// CHECK: @_ZN22testNoexceptConversion6mfptr2E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[DISC_NO_NOEXCEPT]]) to i64), i64 0 },
+// CXX11: @_ZN22testNoexceptConversion15mfptr3_noexceptE = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[DISC_NO_NOEXCEPT]]) to i64), i64 0 },
+// CXX17: @_ZN22testNoexceptConversion15mfptr3_noexceptE = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[DISC_NOEXCEPT:.*]]) to i64), i64 0 },
+
 // CHECK: @_ZTV5Base0 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5Base0,
 // CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual1Ev, i32 0, i64 55600, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 2)),
 // CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual3Ev, i32 0, i64 53007, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 3)),
@@ -438,3 +445,101 @@ void testArrayInit() {
 void testConvertNull() {
   VariadicMethodTy0 t = (VariadicMethodTy0)(MethodTy0{});
 }
+
+namespace testNoexceptConversion {
+
+// CHECK-LABEL: define internal void @__cxx_global_var_init()
+// CXX17: [[ENTRY:.*]]:
+// CHECK: %[[V0:.*]] = load { i64, i64 }, ptr @_ZN22testNoexceptConversion15mfptr0_noexceptE, align 8
+// CXX17: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V0]], 0
+// CXX17: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V0]], 1
+// CXX17: %[[V1:.*]] = and i64 %[[MEMPTR_ADJ]], 1
+// CXX17: %[[IS_VIRTUAL_OFFSET:.*]] = icmp ne i64 %[[V1]], 0
+// CXX17: br i1 %[[IS_VIRTUAL_OFFSET]], label %[[MERGE:.*]], label %[[RESIGN:.*]]
+
+// CXX17: [[RESIGN]]:
+// CXX17: %[[V2:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr
+// CXX17: %[[V3:.*]] = icmp ne ptr %[[V2]], null
+// CXX17: br i1 %[[V3]], label %[[RESIGN_NONNULL:.*]], label %[[RESIGN_CONT:.*]]
+
+// CXX17: [[RESIGN_NONNULL]]:
+// CXX17: %[[V4:.*]] = ptrtoint ptr %[[V2]] to i64
+// CXX17: %[[V5:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V4]], i32 0, i64 [[DISC_NOEXCEPT]], i32 0, i64 [[DISC_NO_NOEXCEPT]])
+// CXX17: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr
+// CXX17: br label %[[RESIGN_CONT]]
+
+// CXX17: [[RESIGN_CONT]]:
+// CXX17: %[[V7:.*]] = phi ptr [ null, %[[RESIGN]] ], [ %[[V6]], %[[RESIGN_NONNULL]] ]
+// CXX17: %[[V8:.*]] = ptrtoint ptr %[[V7]] to i64
+// CXX17: %[[V9:.*]] = insertvalue { i64, i64 } %[[V0]], i64 %[[V8]], 0
+// CXX17: br label %[[MERGE]]
+
+// CXX17: [[MERGE]]:
+// CXX17: %[[V10:.*]] = phi { i64, i64 } [ %[[V0]], %[[ENTRY]] ], [ %[[V9]], %[[RESIGN_CONT]] ]
+// CXX17: store { i64, i64 } %[[V10]], ptr @_ZN22testNoexceptConversion6mfptr4E, align 8
+// CXX11: store { i64, i64 } %[[V0]], ptr @_ZN22testNoexceptConversion6mfptr4E, align 8
+
+// CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test0Ev()
+// CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8
+// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[DISC_NO_NOEXCEPT]]) to i64), i64 0 }, ptr %[[P0]], align 8,
+
+// CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test1Ev()
+// CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8
+// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[DISC_NO_NOEXCEPT]]) to i64), i64 0 }, ptr %[[P0]], align 8,
+
+// CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test2Ev()
+// CXX17: [[ENTRY:.*]]:
+// CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8
+// CHECK: %[[V0:.*]] = load { i64, i64 }, ptr @_ZN22testNoexceptConversion15mfptr0_noexceptE, align 8
+// CXX17: %[[MEMPTR_PTR:.*]] = extractvalue { i64, i64 } %[[V0]], 0
+// CXX17: %[[MEMPTR_ADJ:.*]] = extractvalue { i64, i64 } %[[V0]], 1
+// CXX17: %[[V1:.*]] = and i64 %[[MEMPTR_ADJ]], 1
+// CXX17: %[[IS_VIRTUAL_OFFSET:.*]] = icmp ne i64 %[[V1]], 0
+// CXX17: br i1 %[[IS_VIRTUAL_OFFSET]], label %[[MERGE:.*]], label %[[RESIGN:.*]]
+
+// CXX17: [[RESIGN]]:
+// CXX17: %[[V2:.*]] = inttoptr i64 %[[MEMPTR_PTR]] to ptr
+// CXX17: %[[V3:.*]] = icmp ne ptr %[[V2]], null
+// CXX17: br i1 %[[V3]], label %[[RESIGN_NONNULL:.*]], label %[[RESIGN_CONT:.*]]
+
+// CXX17: [[RESIGN_NONNULL]]:
+// CXX17: %[[V4:.*]] = ptrtoint ptr %[[V2]] to i64
+// CXX17: %[[V5:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V4]], i32 0, i64 [[DISC_NOEXCEPT]], i32 0, i64 [[DISC_NO_NOEXCEPT]])
+// CXX17: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr
+// CXX17: br label %[[RESIGN_CONT]]
+
+// CXX17: [[RESIGN_CONT]]:
+// CXX17: %[[V7:.*]] = phi ptr [ null, %[[RESIGN]] ], [ %[[V6]], %[[RESIGN_NONNULL]] ]
+// CXX17: %[[V8:.*]] = ptrtoint ptr %[[V7]] to i64
+// CXX17: %[[V9:.*]] = insertvalue { i64, i64 } %[[V0]], i64 %[[V8]], 0
+// CXX17: br label %[[MERGE]]
+
+// CXX17: [[MERGE]]:
+// CXX17: %[[V10:.*]] = phi { i64, i64 } [ %[[V0]], %[[ENTRY]] ], [ %[[V9]], %[[RESIGN_CONT]] ]
+// CXX11: store { i64, i64 } %[[V0]], ptr %[[P0]], align 8
+// CXX17: store { i64, i64 } %[[V10]], ptr %[[P0]], align 8
+
+struct S {
+  void nonvirtual_noexcept() noexcept;
+  virtual void virtual_noexcept() noexcept;
+};
+
+void (S::*mfptr0_noexcept)() noexcept;
+void (S::*mfptr1)() = &S::nonvirtual_noexcept;
+void (S::*mfptr2)() = &S::virtual_noexcept;
+void (S::*mfptr3_noexcept)() noexcept = &S::nonvirtual_noexcept;
+void (S::*mfptr4)() = mfptr0_noexcept;
+
+void test0() {
+  void (S::*p0)() = &S::nonvirtual_noexcept;
+}
+
+void test1() {
+  void (S::*p0)() = &S::virtual_noexcept;
+}
+
+void test2() {
+  void (S::*p0)() = mfptr0_noexcept;
+}
+
+}

@ahatanak ahatanak requested review from rjmccall and asl September 17, 2024 21:29
Copy link
Collaborator

@asl asl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, thanks!

@ojhunt
Copy link
Contributor

ojhunt commented Sep 18, 2024

LGTM

if (CGF.CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers &&
CE->getType()->isMemberFunctionPointerType())
V = CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, V);
return V;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we not need similar logic here when casting function pointer types when function pointer type diversity is enabled? Does Sema not use CK_NoOp for those? Maybe we should do the same for member pointer conversions and make sure there's a better cast kind to use.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but that's coincidental, right? The language doesn't semantically guarantee that that conversion is a no-op, it just happens to be under normal conditions, even with function pointer type diversity enabled.

What cast kind do we use if you cast a function pointer to a completely different type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

@rjmccall rjmccall Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the CastKind, not the expression class. We generally treat the conversion side of CastExprs uniformly in CodeGen (although there are some important exceptions).

And we can add new CastKinds if there isn't a good one that covers the operation. Adding a new CastKind is generally much more straightforward than adding a new expression class (which we definitely don't need to do here).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

ahatanak added a commit to ahatanak/llvm-project that referenced this pull request Sep 25, 2024
The new cast kinds are needed to distinguish between no-op conversions
and conversions from pointers to noexcept functions to pointers to
functions without noexcept as the latter can cause function pointers to
be re-signed on arm64e.

See llvm#109056 for background.
ahatanak added a commit to ahatanak/llvm-project that referenced this pull request Sep 25, 2024
The new cast kinds are needed to distinguish between no-op conversions
and conversions from pointers to noexcept functions to pointers to
functions without noexcept as the latter can cause function pointers to
be re-signed on arm64e.

See llvm#109056 for background.
ahatanak added a commit to ahatanak/llvm-project that referenced this pull request Sep 26, 2024
The new cast kinds are needed to distinguish between no-op conversions
and conversions from pointers to noexcept functions to pointers to
functions without noexcept as the latter can cause function pointers to
be re-signed on arm64e.

See llvm#109056 for background.
@@ -924,17 +924,20 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
if (isa<llvm::Constant>(src))
return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));

QualType DstType = E->getType(), SrcType = E->getSubExpr()->getType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SrcType is unused in non-assert builds.

@ahatanak
Copy link
Collaborator Author

This change isn't needed anymore as it was decided that noexcept shouldn't be used to compute discriminators of function and member function pointers (see #106487 (comment)).

@ahatanak ahatanak closed this Jan 14, 2025
@ahatanak
Copy link
Collaborator Author

I meant to close #110048.

@ahatanak ahatanak reopened this Jan 14, 2025
@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Jan 16, 2025
@ahatanak ahatanak changed the title [PAC] Re-sign a pointer to a noexcept member function when it is converted to a pointer to a member function without noexcept [PAC] Ignore noexcept on function type when computing discriminator of member function pointers Jan 16, 2025
@asl
Copy link
Collaborator

asl commented Jan 16, 2025

Looks like ignoring noexcept made the everything even more cleaner :)

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

member function pointers

This fixes a bug where a member function pointer signed using a function
type with noexcept as the discriminator was being authenticated using a
function type without noexcept.

Fixes llvm#106487.
@ahatanak ahatanak force-pushed the ptrauth-noexcept-member-function branch from 52ef0c6 to ca0c74f Compare January 21, 2025 17:00
@ahatanak ahatanak merged commit 485c80e into llvm:main Jan 21, 2025
4 of 6 checks passed
@ahatanak ahatanak deleted the ptrauth-noexcept-member-function branch January 21, 2025 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[PAC] Implicit casts results in no resigns in some cases
6 participants