-
Notifications
You must be signed in to change notification settings - Fork 15.6k
Open
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"crashPrefer [crash-on-valid] or [crash-on-invalid]Prefer [crash-on-valid] or [crash-on-invalid]
Description
Minimal reproducing example:
#include <clang/AST/ASTContext.h>
#include <clang/AST/Decl.h>
#include <clang/AST/DeclarationName.h>
#include <clang/AST/Expr.h>
#include <clang/AST/OperationKinds.h>
#include <clang/AST/Type.h>
#include <clang/Basic/LangOptions.h>
#include <clang/Basic/SourceLocation.h>
#include <clang/Basic/Specifiers.h>
#include <clang/Frontend/ASTUnit.h>
#include <clang/Sema/Sema.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/ADT/APInt.h>
clang::IdentifierInfo *CreateIdentifier(std::string name, clang::ASTContext& ctx ) {
std::string str{""};
for (auto chr : name) {
str.push_back(std::isalnum(chr) ? chr : '_');
}
return &ctx.Idents.get(str);
}
int main(int argc, char *argv[]) {
auto ast = clang::tooling::buildASTFromCode("");
auto rdecl = clang::RecordDecl::Create(ast->getASTContext(), clang::TagTypeKind::TTK_Struct, ast->getASTContext().getTranslationUnitDecl(), clang::SourceLocation(), clang::SourceLocation(), CreateIdentifier("test", ast->getASTContext()));
auto& sema = ast->getSema();
auto chr_ty = ast->getASTContext().getUnsignedWCharType();
auto int_sz = clang::IntegerLiteral::Create( ast->getASTContext(), llvm::APInt(64, 1, false), ast->getASTContext().getIntTypeForBitwidth(64, 0), clang::SourceLocation());
auto arr_ty = ast->getASTContext().getConstantArrayType(chr_ty, llvm::APInt(64, 1, false), int_sz, clang::ArrayType::ArraySizeModifier::Normal, 0);
auto fld = sema.CheckFieldDecl(clang::DeclarationName(CreateIdentifier("test_field", ast->getASTContext())), arr_ty, ast->getASTContext().getTrivialTypeSourceInfo(arr_ty), rdecl, clang::SourceLocation(), false, nullptr, clang::ICIS_NoInit,
clang::SourceLocation(), clang::AccessSpecifier::AS_none,nullptr);
rdecl->completeDefinition();
auto record_ty = ast->getASTContext().getRecordType(rdecl);
clang::CXXScopeSpec ss;
auto dap{clang::DeclAccessPair::make(fld, fld->getAccess())};
auto gv = clang::VarDecl::Create(ast->getASTContext(), ast->getASTContext().getTranslationUnitDecl(), clang::SourceLocation(), clang::SourceLocation(), CreateIdentifier("test_gv", ast->getASTContext()),record_ty,ast->getASTContext().getTrivialTypeSourceInfo(record_ty), clang::SC_None);
auto ref = sema.BuildDeclRefExpr(gv, gv->getType(), clang::ExprValueKind::VK_LValue, clang::SourceLocation(), nullptr);
auto fld_ref = sema.BuildFieldReferenceExpr(ref, false, clang::SourceLocation(),ss, fld, dap,clang::DeclarationNameInfo());
assert(fld_ref.isUsable());
assert(fld_ref.get()->isFlexibleArrayMemberLike(ast->getASTContext(), clang::LangOptions::StrictFlexArraysLevelKind::Default, true));
}isFlexibleArrayMemberLike uses the source type info to attempt to determine if the size is the result of a macro. This behavior can lead to a nullptr being passed to dyn_cast if the source range associated with the type info is an empty location.
Unfortunately, CheckArrayAccess uses ignoreTemplate meaning in cases where the API is used for code generation (ie. when source locs will not exist) a crash will occur.
An example patch that treats type info without a location as a non-macro size is available here
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"crashPrefer [crash-on-valid] or [crash-on-invalid]Prefer [crash-on-valid] or [crash-on-invalid]