-
Couldn't load subscription status.
- Fork 15k
[PAC][clang] Correct handling of ptrauth queries of incomplete types #164528
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1618,8 +1618,26 @@ void ASTContext::setRelocationInfoForCXXRecord( | |
| RelocatableClasses.insert({D, Info}); | ||
| } | ||
|
|
||
| // In future we may want to distinguish the presence or absence of address | ||
| // discrimination, from the inability to determine the presence. For now we rely | ||
| // on all source facing interfaces (type trait queries, etc) diagnosing and | ||
| // reporting an error before reaching these paths. | ||
| static bool canDeterminePointerAuthContent(QualType Type) { | ||
| if (Type->isIncompleteType() || Type->isDependentType()) | ||
|
||
| return false; | ||
| const TagDecl *Decl = Type->getAsTagDecl(); | ||
| return !Decl || !Decl->getDefinition()->isInvalidDecl(); | ||
|
||
| } | ||
| static bool canDeterminePointerAuthContent(const ASTContext &Ctx, | ||
| const TagDecl *Decl) { | ||
| CanQualType DeclType = Ctx.getCanonicalTagType(Decl); | ||
| return canDeterminePointerAuthContent(DeclType); | ||
| } | ||
|
|
||
| static bool primaryBaseHaseAddressDiscriminatedVTableAuthentication( | ||
| const ASTContext &Context, const CXXRecordDecl *Class) { | ||
| if (!canDeterminePointerAuthContent(Context, Class)) | ||
| return false; | ||
| if (!Class->isPolymorphic()) | ||
| return false; | ||
| const CXXRecordDecl *BaseType = Context.baseForVTableAuthentication(Class); | ||
|
|
@@ -1639,7 +1657,7 @@ ASTContext::findPointerAuthContent(QualType T) const { | |
| assert(isPointerAuthenticationAvailable()); | ||
|
|
||
| T = T.getCanonicalType(); | ||
| if (T->isDependentType()) | ||
| if (!canDeterminePointerAuthContent(T)) | ||
| return PointerAuthContent::None; | ||
|
|
||
| if (T.hasAddressDiscriminatedPointerAuth()) | ||
|
|
@@ -3230,6 +3248,7 @@ QualType ASTContext::removeAddrSpaceQualType(QualType T) const { | |
|
|
||
| uint16_t | ||
| ASTContext::getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD) { | ||
| assert(canDeterminePointerAuthContent(*this, RD)); | ||
| assert(RD->isPolymorphic() && | ||
| "Attempted to get vtable pointer discriminator on a monomorphic type"); | ||
| std::unique_ptr<MangleContext> MC(createMangleContext()); | ||
|
|
@@ -3517,7 +3536,9 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, | |
| uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) { | ||
| assert(!T->isDependentType() && | ||
| "cannot compute type discriminator of a dependent type"); | ||
|
|
||
| assert(canDeterminePointerAuthContent(T) && | ||
| "cannot compute type discriminator of an incomplete or otherwise " | ||
| "invalid type"); | ||
| SmallString<256> Str; | ||
| llvm::raw_svector_ostream Out(Str); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // RUN: %clang_cc1 -fptrauth-intrinsics -fsyntax-only -ferror-limit 1 -verify -std=c++26 %s | ||
| // RUN: %clang_cc1 -fptrauth-intrinsics -fsyntax-only -ferror-limit 1 -verify -std=c++03 %s | ||
| // RUN: %clang_cc1 -fsyntax-only -ferror-limit 1 -verify -std=c++03 %s | ||
|
|
||
|
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you test without -fsyntax-only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have added, is there any difference in behavior between -fsyntax-only and not if there are errors? (i.e. do further passes running prior to the abort) |
||
| /// Force two errors so we hit the error limit leading to skip of template instantiation | ||
| # "" // expected-error {{invalid preprocessing directive}} | ||
| # "" | ||
| // expected-error@* {{too many errors emitted}} | ||
|
|
||
| template <typename> | ||
| struct a {}; | ||
| struct test_polymorphic { | ||
| virtual ~test_polymorphic(); | ||
| a<int> field; | ||
| }; | ||
| static_assert(__is_trivially_relocatable(test_polymorphic)); | ||
|
|
||
| struct test_struct { | ||
| test_struct(int) {} | ||
| void test_instantiate() { | ||
| test_struct d(0); | ||
| } | ||
| void test_type_trait_query() { | ||
| __is_trivially_relocatable(test_struct); | ||
| } | ||
| a<int> e; | ||
| }; | ||
|
|
||
| struct test_subclass : test_struct { | ||
| test_subclass() : test_struct(0) { | ||
| } | ||
|
|
||
| void test_subclass_instantiation() { | ||
| test_subclass subclass{}; | ||
| } | ||
| void test_subclass_type_trait_query() { | ||
| __is_trivially_relocatable(test_subclass); | ||
| } | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cor3ntin is there a better way to do this? It seems like there should be