Skip to content

Commit cdffd55

Browse files
committed
[ClangImporter] Check for builtin conformance in importNumericLiteral
Make sure the destination type actually conforms to the corresponding builtin literal protocol before attempting to import it. We may want to consider allowing any type that conforms to the non-builtin literal protocol, but I want to keep this patch low risk and just ensure we at least don't crash for now. rdar://156524292
1 parent 33e6c0f commit cdffd55

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/ClangImporter/ImportMacro.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
125125
return nullptr;
126126
}
127127

128+
auto &ctx = DC->getASTContext();
129+
auto *constantTyNominal = constantType->getAnyNominal();
130+
if (!constantTyNominal)
131+
return nullptr;
132+
128133
if (auto *integer = dyn_cast<clang::IntegerLiteral>(parsed)) {
129134
// Determine the value.
130135
llvm::APSInt value{integer->getValue(), clangTy->isUnsignedIntegerType()};
@@ -140,6 +145,16 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
140145
}
141146
}
142147

148+
// Make sure the destination type actually conforms to the builtin literal
149+
// protocol before attempting to import, otherwise we'll crash since
150+
// `createConstant` expects it to.
151+
// FIXME: We ought to be careful checking conformance here since it can
152+
// result in cycles. Additionally we ought to consider checking for the
153+
// non-builtin literal protocol to allow any ExpressibleByIntegerLiteral
154+
// type to be supported.
155+
if (!ctx.getIntBuiltinInitDecl(constantTyNominal))
156+
return nullptr;
157+
143158
return createMacroConstant(Impl, MI, name, DC, constantType,
144159
clang::APValue(value),
145160
ConstantConvertKind::None,
@@ -158,6 +173,16 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
158173
value.changeSign();
159174
}
160175

176+
// Make sure the destination type actually conforms to the builtin literal
177+
// protocol before attempting to import, otherwise we'll crash since
178+
// `createConstant` expects it to.
179+
// FIXME: We ought to be careful checking conformance here since it can
180+
// result in cycles. Additionally we ought to consider checking for the
181+
// non-builtin literal protocol to allow any ExpressibleByFloatLiteral
182+
// type to be supported.
183+
if (!ctx.getFloatBuiltinInitDecl(constantTyNominal))
184+
return nullptr;
185+
161186
return createMacroConstant(Impl, MI, name, DC, constantType,
162187
clang::APValue(value),
163188
ConstantConvertKind::None,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-frontend -typecheck -verify %t/main.swift -I %t -verify-additional-file %t/cmodule.h
4+
5+
// REQUIRES: objc_interop
6+
// REQUIRES: OS=macosx
7+
8+
//--- cmodule.h
9+
#import <CoreGraphics/CoreGraphics.h>
10+
#define intLiteralCGFloat ((CGFloat)0)
11+
// expected-note@-1 {{invalid numeric literal}}
12+
// expected-note@-2 {{macro 'intLiteralCGFloat' unavailable (cannot import)}}
13+
#define floatLiteralCGFloat ((CGFloat)0.0)
14+
// expected-note@-1 {{invalid numeric literal}}
15+
// expected-note@-2 {{macro 'floatLiteralCGFloat' unavailable (cannot import)}}
16+
17+
//--- module.modulemap
18+
module CModule [system] {
19+
header "cmodule.h"
20+
export *
21+
}
22+
23+
//--- main.swift
24+
import CModule
25+
26+
// Make sure we don't crash when attempting to import these.
27+
_ = intLiteralCGFloat // expected-error {{cannot find 'intLiteralCGFloat' in scope}}
28+
_ = floatLiteralCGFloat // expected-error {{cannot find 'floatLiteralCGFloat' in scope}}

0 commit comments

Comments
 (0)