This revision was automatically updated to reflect the committed changes. Closed by commit rG1ba6fb929396: [clang] Fix a crash when passing a C structure of incompatible type to a… (authored by ArcsinX, committed by riccibruno).
Changed prior to commit: https://reviews.llvm.org/D82805?vs=274789&id=276457#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D82805/new/ https://reviews.llvm.org/D82805 Files: clang/lib/Sema/SemaInit.cpp clang/test/Sema/init-ref-c.c Index: clang/test/Sema/init-ref-c.c =================================================================== --- /dev/null +++ clang/test/Sema/init-ref-c.c @@ -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'}} +} \ No newline at end of file Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4693,6 +4693,9 @@ } /// 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 @@ // 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; + } } }
Index: clang/test/Sema/init-ref-c.c =================================================================== --- /dev/null +++ clang/test/Sema/init-ref-c.c @@ -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'}} +} \ No newline at end of file Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4693,6 +4693,9 @@ } /// 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 @@ // 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; + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits