Skip to content

Commit 16e4785

Browse files
authored
Merge pull request #3629 from IngmarStein/master
[ClangImporter] fix crash when importing macros with bitwise operators
2 parents 0358235 + 48079e7 commit 16e4785

File tree

6 files changed

+28
-9
lines changed

6 files changed

+28
-9
lines changed

lib/ClangImporter/ImportMacro.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,21 +476,33 @@ static ValueDecl *importMacro(ClangImporter::Implementation &impl,
476476

477477
auto firstInteger = firstValue.getInt();
478478
auto secondInteger = secondValue.getInt();
479+
auto firstBitWidth = firstInteger.getBitWidth();
480+
auto secondBitWidth = secondInteger.getBitWidth();
479481
auto type = firstConstant.second;
480482

481483
clang::APValue value;
482484
if (tokenI[1].is(clang::tok::pipe)) {
483-
if (firstInteger.getBitWidth() == secondInteger.getBitWidth()) {
484-
value = clang::APValue(firstInteger | secondInteger);
485-
} else {
486-
return nullptr;
485+
if (firstBitWidth < secondBitWidth) {
486+
firstInteger = firstInteger.extend(secondBitWidth);
487+
type = secondConstant.second;
488+
} else if (secondBitWidth < firstBitWidth) {
489+
secondInteger = secondInteger.extend(firstBitWidth);
490+
type = firstConstant.second;
487491
}
492+
firstInteger.setIsUnsigned(true);
493+
secondInteger.setIsUnsigned(true);
494+
value = clang::APValue(firstInteger | secondInteger);
488495
} else if (tokenI[1].is(clang::tok::amp)) {
489-
if (firstInteger.getBitWidth() == secondInteger.getBitWidth()) {
490-
value = clang::APValue(firstInteger & secondInteger);
491-
} else {
492-
return nullptr;
496+
if (firstBitWidth < secondBitWidth) {
497+
firstInteger = firstInteger.extend(secondBitWidth);
498+
type = secondConstant.second;
499+
} else if (secondBitWidth < firstBitWidth) {
500+
secondInteger = secondInteger.extend(firstBitWidth);
501+
type = firstConstant.second;
493502
}
503+
firstInteger.setIsUnsigned(true);
504+
secondInteger.setIsUnsigned(true);
505+
value = clang::APValue(firstInteger & secondInteger);
494506
} else if (tokenI[1].is(clang::tok::pipepipe)) {
495507
auto firstBool = firstInteger.getBoolValue();
496508
auto secondBool = firstInteger.getBoolValue();

test/IDE/Inputs/mock-sdk/Foo.annotated.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ class <loc>FooClassDerived</loc> : <ref:Class>FooClassBase</ref>, <ref:Protocol>
195195
<decl:Var>var <loc>FOO_MACRO_11</loc>: <ref:Struct>Int</ref> { get }</decl>
196196
<decl:Var>var <loc>FOO_MACRO_OR</loc>: <ref:Struct>Int32</ref> { get }</decl>
197197
<decl:Var>var <loc>FOO_MACRO_AND</loc>: <ref:Struct>Int32</ref> { get }</decl>
198+
<decl:Var>var <loc>FOO_MACRO_BITWIDTH</loc>: <ref:Struct>UInt64</ref> { get }</decl>
199+
<decl:Var>var <loc>FOO_MACRO_SIGNED</loc>: <ref:Struct>Int32</ref> { get }</decl>
198200
<decl:Var>var <loc>FOO_MACRO_REDEF_1</loc>: <ref:Struct>Int32</ref> { get }</decl>
199201
<decl:Var>var <loc>FOO_MACRO_REDEF_2</loc>: <ref:Struct>Int32</ref> { get }</decl>
200202
<decl:Func>func <loc>theLastDeclInFoo()</loc></decl>

test/IDE/Inputs/mock-sdk/Foo.framework/Headers/Foo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ typedef int typedef_int_t;
197197
#define FOO_MACRO_OR (FOO_MACRO_2 | FOO_MACRO_6)
198198
#define FOO_MACRO_AND (FOO_MACRO_2 & FOO_MACRO_6)
199199
#define FOO_MACRO_BITWIDTH (FOO_MACRO_4 & FOO_MACRO_5)
200+
#define FOO_MACRO_SIGNED (FOO_MACRO_2 & FOO_MACRO_4)
200201

201202
#define FOO_MACRO_UNDEF_1 0
202203
#undef FOO_MACRO_UNDEF_1

test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ var FOO_MACRO_10: Int16 { get }
195195
var FOO_MACRO_11: Int { get }
196196
var FOO_MACRO_OR: Int32 { get }
197197
var FOO_MACRO_AND: Int32 { get }
198+
var FOO_MACRO_BITWIDTH: UInt64 { get }
199+
var FOO_MACRO_SIGNED: Int32 { get }
198200
var FOO_MACRO_REDEF_1: Int32 { get }
199201
var FOO_MACRO_REDEF_2: Int32 { get }
200202
func theLastDeclInFoo()

test/IDE/Inputs/mock-sdk/Foo.printed.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ var FOO_MACRO_10: Int16 { get }
233233
var FOO_MACRO_11: Int { get }
234234
var FOO_MACRO_OR: Int32 { get }
235235
var FOO_MACRO_AND: Int32 { get }
236+
var FOO_MACRO_BITWIDTH: UInt64 { get }
237+
var FOO_MACRO_SIGNED: Int32 { get }
236238

237239
var FOO_MACRO_REDEF_1: Int32 { get }
238240

test/IDE/complete_from_clang_framework.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func testCompleteModuleQualifiedFoo2() {
146146
Foo#^CLANG_QUAL_FOO_2^#
147147
// If the number of results below changes, then you need to add a result to the
148148
// list below.
149-
// CLANG_QUAL_FOO_2: Begin completions, 73 items
149+
// CLANG_QUAL_FOO_2: Begin completions, 75 items
150150
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassBase[#FooClassBase#]{{; name=.+$}}
151151
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassDerived[#FooClassDerived#]{{; name=.+$}}
152152
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .ClassWithInternalProt[#ClassWithInternalProt#]{{; name=.+$}}

0 commit comments

Comments
 (0)