summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaType.cpp')
-rw-r--r--clang/lib/Sema/SemaType.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 33b1d8ca4dfa..eba7267904fb 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2552,6 +2552,12 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
return true;
}
+ // __ptrauth is illegal on a function return type.
+ if (T.getPointerAuth()) {
+ Diag(Loc, diag::err_ptrauth_qualifier_invalid) << T << 0;
+ return true;
+ }
+
if (T.hasNonTrivialToPrimitiveDestructCUnion() ||
T.hasNonTrivialToPrimitiveCopyCUnion())
checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn,
@@ -2657,6 +2663,10 @@ QualType Sema::BuildFunctionType(QualType T,
} else if (ParamType->isWebAssemblyTableType()) {
Diag(Loc, diag::err_wasm_table_as_function_parameter);
Invalid = true;
+ } else if (ParamType.getPointerAuth()) {
+ // __ptrauth is illegal on a function return type.
+ Diag(Loc, diag::err_ptrauth_qualifier_invalid) << T << 1;
+ Invalid = true;
}
// C++2a [dcl.fct]p4:
@@ -4974,6 +4984,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
}
+ // __ptrauth is illegal on a function return type.
+ if (T.getPointerAuth()) {
+ S.Diag(DeclType.Loc, diag::err_ptrauth_qualifier_invalid) << T << 0;
+ }
+
if (LangOpts.OpenCL) {
// OpenCL v2.0 s6.12.5 - A block cannot be the return value of a
// function.
@@ -8333,6 +8348,65 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
CurType = S.Context.getVectorType(CurType, numElts, VecKind);
}
+/// Handle the __ptrauth qualifier.
+static void HandlePtrAuthQualifier(ASTContext &Ctx, QualType &T,
+ const ParsedAttr &Attr, Sema &S) {
+
+ assert((Attr.getNumArgs() > 0 && Attr.getNumArgs() <= 3) &&
+ "__ptrauth qualifier takes between 1 and 3 arguments");
+ Expr *KeyArg = Attr.getArgAsExpr(0);
+ Expr *IsAddressDiscriminatedArg =
+ Attr.getNumArgs() >= 2 ? Attr.getArgAsExpr(1) : nullptr;
+ Expr *ExtraDiscriminatorArg =
+ Attr.getNumArgs() >= 3 ? Attr.getArgAsExpr(2) : nullptr;
+
+ unsigned Key;
+ if (S.checkConstantPointerAuthKey(KeyArg, Key)) {
+ Attr.setInvalid();
+ return;
+ }
+ assert(Key <= PointerAuthQualifier::MaxKey && "ptrauth key is out of range");
+
+ bool IsInvalid = false;
+ unsigned IsAddressDiscriminated, ExtraDiscriminator;
+ IsInvalid |= !S.checkPointerAuthDiscriminatorArg(IsAddressDiscriminatedArg,
+ Sema::PADAK_AddrDiscPtrAuth,
+ IsAddressDiscriminated);
+ IsInvalid |= !S.checkPointerAuthDiscriminatorArg(
+ ExtraDiscriminatorArg, Sema::PADAK_ExtraDiscPtrAuth, ExtraDiscriminator);
+
+ if (IsInvalid) {
+ Attr.setInvalid();
+ return;
+ }
+
+ if (!T->isSignableType() && !T->isDependentType()) {
+ S.Diag(Attr.getLoc(), diag::err_ptrauth_qualifier_nonpointer) << T;
+ Attr.setInvalid();
+ return;
+ }
+
+ if (T.getPointerAuth()) {
+ S.Diag(Attr.getLoc(), diag::err_ptrauth_qualifier_redundant)
+ << T << Attr.getAttrName()->getName();
+ Attr.setInvalid();
+ return;
+ }
+
+ if (!S.getLangOpts().PointerAuthIntrinsics) {
+ S.Diag(Attr.getLoc(), diag::err_ptrauth_disabled) << Attr.getRange();
+ Attr.setInvalid();
+ return;
+ }
+
+ assert((!IsAddressDiscriminatedArg || IsAddressDiscriminated <= 1) &&
+ "address discriminator arg should be either 0 or 1");
+ PointerAuthQualifier Qual = PointerAuthQualifier::Create(
+ Key, IsAddressDiscriminated, ExtraDiscriminator,
+ PointerAuthenticationMode::SignAndAuth, false, false);
+ T = S.Context.getPointerAuthType(T, Qual);
+}
+
/// HandleArmSveVectorBitsTypeAttr - The "arm_sve_vector_bits" attribute is
/// used to create fixed-length versions of sizeless SVE types defined by
/// the ACLE, such as svint32_t and svbool_t.
@@ -8788,6 +8862,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
HandleOpenCLAccessAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr();
break;
+ case ParsedAttr::AT_PointerAuth:
+ HandlePtrAuthQualifier(state.getSema().Context, type, attr,
+ state.getSema());
+ attr.setUsedAsTypeAttr();
+ break;
case ParsedAttr::AT_LifetimeBound:
if (TAL == TAL_DeclChunk)
HandleLifetimeBoundAttr(state, type, attr);