mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-12 09:41:26 +00:00
[ASTImporter] Fix inequality of functions with different attributes
Summary: FunctionType::ExtInfo holds such properties of a function which are needed mostly for code gen. We should not compare these bits when checking for structural equivalency. Checking ExtInfo caused false ODR errors during CTU analysis (of tmux). Reviewers: a_sidorin, a.sidorin, shafik Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits Differential Revision: https://reviews.llvm.org/D53699 llvm-svn: 352050
This commit is contained in:
parent
66038ffa13
commit
41f2046642
@ -296,6 +296,32 @@ static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Determine structural equivalence based on the ExtInfo of functions. This
|
||||
/// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
|
||||
/// conventions bits but must not compare some other bits.
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
FunctionType::ExtInfo EI1,
|
||||
FunctionType::ExtInfo EI2) {
|
||||
// Compatible functions must have compatible calling conventions.
|
||||
if (EI1.getCC() != EI2.getCC())
|
||||
return false;
|
||||
|
||||
// Regparm is part of the calling convention.
|
||||
if (EI1.getHasRegParm() != EI2.getHasRegParm())
|
||||
return false;
|
||||
if (EI1.getRegParm() != EI2.getRegParm())
|
||||
return false;
|
||||
|
||||
if (EI1.getProducesResult() != EI2.getProducesResult())
|
||||
return false;
|
||||
if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
|
||||
return false;
|
||||
if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Determine structural equivalence of two types.
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
QualType T1, QualType T2) {
|
||||
@ -539,7 +565,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
|
||||
Function2->getReturnType()))
|
||||
return false;
|
||||
if (Function1->getExtInfo() != Function2->getExtInfo())
|
||||
if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
|
||||
Function2->getExtInfo()))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -370,6 +370,31 @@ TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
|
||||
auto t = makeNamedDecls(
|
||||
"__attribute__((noreturn)) void foo();",
|
||||
" void foo();",
|
||||
Lang_C);
|
||||
EXPECT_TRUE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceFunctionTest,
|
||||
FunctionsWithDifferentCallingConventions) {
|
||||
auto t = makeNamedDecls(
|
||||
"__attribute__((fastcall)) void foo();",
|
||||
"__attribute__((ms_abi)) void foo();",
|
||||
Lang_C);
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
|
||||
auto t = makeNamedDecls(
|
||||
"__attribute__((no_caller_saved_registers)) void foo();",
|
||||
" void foo();",
|
||||
Lang_C);
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user