[clang] 1ba6fb9 - [clang] Fix a crash when passing a C structure of incompatible type to a function with a reference parameter.
Bruno Ricci via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 8 09:01:02 PDT 2020
Author: Aleksandr Platonov
Date: 2020-07-08T16:57:54+01:00
New Revision: 1ba6fb9293967de21ae33be10603bf5ae0ce1c96
URL: https://github.com/llvm/llvm-project/commit/1ba6fb9293967de21ae33be10603bf5ae0ce1c96
DIFF: https://github.com/llvm/llvm-project/commit/1ba6fb9293967de21ae33be10603bf5ae0ce1c96.diff
LOG: [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 at huawei.com>
Added:
clang/test/Sema/init-ref-c.c
Modified:
clang/lib/Sema/SemaInit.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d46e7f86d6b3..eb07de65d266 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -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;
+ }
}
}
diff --git a/clang/test/Sema/init-ref-c.c b/clang/test/Sema/init-ref-c.c
new file mode 100644
index 000000000000..38d8c44e2fdf
--- /dev/null
+++ b/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
More information about the cfe-commits
mailing list