mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-07 10:02:22 +00:00
[Sema] Make typeof(OverloadedFunctionName) not a pointer.
We were sometimes doing a function->pointer conversion in Sema::CheckPlaceholderExpr, which isn't the job of CheckPlaceholderExpr. So, when we saw typeof(OverloadedFunctionName), where OverloadedFunctionName referenced a name with only one function that could have its address taken, we'd give back a function pointer type instead of a function type. This is incorrect. I kept the logic for doing the function pointer conversion in resolveAndFixAddressOfOnlyViableOverloadCandidate because it was more consistent with existing ResolveAndFix* methods. llvm-svn: 302506
This commit is contained in:
parent
b35ef2a599
commit
1dbfa856b1
@ -2726,7 +2726,8 @@ public:
|
||||
resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
|
||||
DeclAccessPair &FoundResult);
|
||||
|
||||
bool resolveAndFixAddressOfOnlyViableOverloadCandidate(ExprResult &SrcExpr);
|
||||
bool resolveAndFixAddressOfOnlyViableOverloadCandidate(
|
||||
ExprResult &SrcExpr, bool DoFunctionPointerConversion = false);
|
||||
|
||||
FunctionDecl *
|
||||
ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
|
||||
|
@ -1871,7 +1871,8 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,
|
||||
// No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization
|
||||
// preserves Result.
|
||||
Result = E;
|
||||
if (!Self.resolveAndFixAddressOfOnlyViableOverloadCandidate(Result))
|
||||
if (!Self.resolveAndFixAddressOfOnlyViableOverloadCandidate(
|
||||
Result, /*DoFunctionPointerConversion=*/true))
|
||||
return false;
|
||||
return Result.isUsable();
|
||||
}
|
||||
|
@ -11210,12 +11210,12 @@ Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
|
||||
/// \brief Given an overloaded function, tries to turn it into a non-overloaded
|
||||
/// function reference using resolveAddressOfOnlyViableOverloadCandidate. This
|
||||
/// will perform access checks, diagnose the use of the resultant decl, and, if
|
||||
/// necessary, perform a function-to-pointer decay.
|
||||
/// requested, potentially perform a function-to-pointer decay.
|
||||
///
|
||||
/// Returns false if resolveAddressOfOnlyViableOverloadCandidate fails.
|
||||
/// Otherwise, returns true. This may emit diagnostics and return true.
|
||||
bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate(
|
||||
ExprResult &SrcExpr) {
|
||||
ExprResult &SrcExpr, bool DoFunctionPointerConverion) {
|
||||
Expr *E = SrcExpr.get();
|
||||
assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload");
|
||||
|
||||
@ -11230,7 +11230,7 @@ bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate(
|
||||
DiagnoseUseOfDecl(Found, E->getExprLoc());
|
||||
CheckAddressOfMemberAccess(E, DAP);
|
||||
Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found);
|
||||
if (Fixed->getType()->isFunctionType())
|
||||
if (DoFunctionPointerConverion && Fixed->getType()->isFunctionType())
|
||||
SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false);
|
||||
else
|
||||
SrcExpr = Fixed;
|
||||
|
@ -151,3 +151,18 @@ void dropping_qualifiers_is_incompatible() {
|
||||
foo(ccharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@148{{candidate function}} expected-note@149{{candidate function}}
|
||||
foo(vcharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@148{{candidate function}} expected-note@149{{candidate function}}
|
||||
}
|
||||
|
||||
// Bug: we used to treat `__typeof__(foo)` as though it was `__typeof__(&foo)`
|
||||
// if `foo` was overloaded with only one function that could have its address
|
||||
// taken.
|
||||
void typeof_function_is_not_a_pointer() {
|
||||
void not_a_pointer(void *) __attribute__((overloadable));
|
||||
void not_a_pointer(char *__attribute__((pass_object_size(1))))
|
||||
__attribute__((overloadable));
|
||||
|
||||
__typeof__(not_a_pointer) *fn;
|
||||
|
||||
void take_fn(void (*)(void *));
|
||||
// if take_fn is passed a void (**)(void *), we'll get a warning.
|
||||
take_fn(fn);
|
||||
}
|
||||
|
@ -499,3 +499,17 @@ void run() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace TypeOfFn {
|
||||
template <typename T, typename U>
|
||||
struct is_same;
|
||||
|
||||
template <typename T> struct is_same<T, T> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
void foo(int a) __attribute__((enable_if(a, "")));
|
||||
void foo(float a) __attribute__((enable_if(1, "")));
|
||||
|
||||
static_assert(is_same<__typeof__(foo)*, decltype(&foo)>::value, "");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user