forked from OSchip/llvm-project
[clang] Fix a crash when passing a C structure of incompatible type to a function with a reference parameter.
__builtin_va_*() and __builtin_ms_va_*() are declared as functions with a parameter of reference type. This patch fixes a crash when using these functions in C where an argument of structure type is incompatible with the parameter type. Differential Revision: https://reviews.llvm.org/D82805 Reviewed By: riccibruno Patch by: Aleksandr Platonov <platonov.aleksandr@huawei.com>
This commit is contained in:
parent
9d8b4defd3
commit
1ba6fb9293
|
@ -4693,6 +4693,9 @@ static bool isNonReferenceableGLValue(Expr *E) {
|
|||
}
|
||||
|
||||
/// Reference initialization without resolving overloaded functions.
|
||||
///
|
||||
/// We also can get here in C if we call a builtin which is declared as
|
||||
/// a function with a parameter of reference type (such as __builtin_va_end()).
|
||||
static void TryReferenceInitializationCore(Sema &S,
|
||||
const InitializedEntity &Entity,
|
||||
const InitializationKind &Kind,
|
||||
|
@ -4769,15 +4772,20 @@ static void TryReferenceInitializationCore(Sema &S,
|
|||
// an rvalue. DR1287 removed the "implicitly" here.
|
||||
if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
|
||||
(isLValueRef || InitCategory.isRValue())) {
|
||||
ConvOvlResult = TryRefInitWithConversionFunction(
|
||||
S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
|
||||
/*IsLValueRef*/ isLValueRef, Sequence);
|
||||
if (ConvOvlResult == OR_Success)
|
||||
return;
|
||||
if (ConvOvlResult != OR_No_Viable_Function)
|
||||
Sequence.SetOverloadFailure(
|
||||
InitializationSequence::FK_ReferenceInitOverloadFailed,
|
||||
ConvOvlResult);
|
||||
if (S.getLangOpts().CPlusPlus) {
|
||||
// Try conversion functions only for C++.
|
||||
ConvOvlResult = TryRefInitWithConversionFunction(
|
||||
S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
|
||||
/*IsLValueRef*/ isLValueRef, Sequence);
|
||||
if (ConvOvlResult == OR_Success)
|
||||
return;
|
||||
if (ConvOvlResult != OR_No_Viable_Function)
|
||||
Sequence.SetOverloadFailure(
|
||||
InitializationSequence::FK_ReferenceInitOverloadFailed,
|
||||
ConvOvlResult);
|
||||
} else {
|
||||
ConvOvlResult = OR_No_Viable_Function;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// RUN: %clang_cc1 -triple arm-unknown-gnu -fsyntax-only -verify %s
|
||||
|
||||
void f() {
|
||||
struct EmptyStruct {};
|
||||
struct EmptyStruct S;
|
||||
__builtin_va_end(S); // no-crash, expected-error {{non-const lvalue reference to type '__builtin_va_list' cannot bind to a value of unrelated type 'struct EmptyStruct'}}
|
||||
}
|
Loading…
Reference in New Issue