Skip to content

Commit

Permalink
[clang][NFC] Factor out VLA checks in type traits (#88646)
Browse files Browse the repository at this point in the history
This is a follow-up to #88473 suggested by @cor3ntin in
#88473 (comment).
  • Loading branch information
Endilll committed Apr 14, 2024
1 parent c6f9c84 commit d48d6ba
Showing 1 changed file with 31 additions and 28 deletions.
59 changes: 31 additions & 28 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5012,6 +5012,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return From;
}

/// Checks that type T is not a VLA.
///
/// @returns @c true if @p T is VLA and a diagnostic was emitted,
/// @c false otherwise.
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
clang::tok::TokenKind TypeTraitID) {
if (!T->getType()->isVariableArrayType())
return false;

S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
<< 1 << TypeTraitID;
return true;
}

/// Check the completeness of a type in a unary type trait.
///
/// If the particular type trait requires a complete type, tries to complete
Expand Down Expand Up @@ -5188,7 +5202,9 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
}

static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
SourceLocation KeyLoc, QualType T) {
SourceLocation KeyLoc,
TypeSourceInfo *TInfo) {
QualType T = TInfo->getType();
assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");

ASTContext &C = Self.Context;
Expand All @@ -5205,21 +5221,13 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
case UTT_IsArray:
return T->isArrayType();
case UTT_IsBoundedArray:
if (!T->isVariableArrayType()) {
return T->isArrayType() && !T->isIncompleteArrayType();
}

Self.Diag(KeyLoc, diag::err_vla_unsupported)
<< 1 << tok::kw___is_bounded_array;
return false;
if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))
return false;
return T->isArrayType() && !T->isIncompleteArrayType();
case UTT_IsUnboundedArray:
if (!T->isVariableArrayType()) {
return T->isIncompleteArrayType();
}

Self.Diag(KeyLoc, diag::err_vla_unsupported)
<< 1 << tok::kw___is_unbounded_array;
return false;
if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))
return false;
return T->isIncompleteArrayType();
case UTT_IsPointer:
return T->isAnyPointerType();
case UTT_IsNullPointer:
Expand Down Expand Up @@ -5631,7 +5639,7 @@ static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
return false;

if (Kind <= UTT_Last)
return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType());
return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);

// Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
// alongside the IsConstructible traits to avoid duplication.
Expand Down Expand Up @@ -6093,12 +6101,9 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI
Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
diag::err_incomplete_type);

if (LhsT->isVariableArrayType())
Self.Diag(Lhs->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
<< 1 << tok::kw___is_layout_compatible;
if (RhsT->isVariableArrayType())
Self.Diag(Rhs->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
<< 1 << tok::kw___is_layout_compatible;
DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);

return Self.IsLayoutCompatible(LhsT, RhsT);
}
case BTT_IsPointerInterconvertibleBaseOf: {
Expand All @@ -6108,12 +6113,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI
diag::err_incomplete_type);
}

if (LhsT->isVariableArrayType())
Self.Diag(Lhs->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
<< 1 << tok::kw___is_pointer_interconvertible_base_of;
if (RhsT->isVariableArrayType())
Self.Diag(Rhs->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
<< 1 << tok::kw___is_pointer_interconvertible_base_of;
DiagnoseVLAInCXXTypeTrait(Self, Lhs,
tok::kw___is_pointer_interconvertible_base_of);
DiagnoseVLAInCXXTypeTrait(Self, Rhs,
tok::kw___is_pointer_interconvertible_base_of);

return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
}
Expand Down

0 comments on commit d48d6ba

Please sign in to comment.