Skip to content

Commit e4f3735

Browse files
authored
[Clang] fix crash by avoiding invalidation of extern main declaration during strictness checks (#104594)
Fixes #104570
1 parent ebe7265 commit e4f3735

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12230,12 +12230,9 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) {
1223012230
// The main function shall not be declared with a linkage-specification.
1223112231
if (FD->isExternCContext() ||
1223212232
(FD->isExternCXXContext() &&
12233-
FD->getDeclContext()->getRedeclContext()->isTranslationUnit())) {
12233+
FD->getDeclContext()->getRedeclContext()->isTranslationUnit()))
1223412234
Diag(FD->getLocation(), diag::ext_main_invalid_linkage_specification)
1223512235
<< FD->getLanguageLinkage();
12236-
FD->setInvalidDecl();
12237-
return;
12238-
}
1223912236

1224012237
// C++11 [basic.start.main]p3:
1224112238
// A program that [...] declares main to be inline, static or

clang/test/CXX/basic/basic.start/basic.start.main/p3.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -DTEST11
1212
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -DTEST12
1313
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -DTEST13
14+
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s -DTEST14
15+
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm-only -verify -pedantic %s -DTEST15
1416

1517
#if TEST1
1618
int main; // expected-error{{main cannot be declared as a variable in the global scope}}
@@ -78,12 +80,14 @@ namespace ns {
7880
extern "C" struct A { int main(); }; // ok
7981

8082
namespace c {
81-
extern "C" void main(); // expected-warning {{'main' should not be 'extern "C"'}}
83+
extern "C" void main(); // expected-error {{'main' must return 'int'}} \
84+
// expected-warning {{'main' should not be 'extern "C"'}}
8285
}
8386

8487
extern "C" {
8588
namespace Z {
86-
void main(); // expected-warning {{'main' should not be 'extern "C"'}}
89+
void main(); // expected-error {{'main' must return 'int'}} \
90+
// expected-warning {{'main' should not be 'extern "C"'}}
8791
}
8892
}
8993

@@ -102,11 +106,6 @@ extern "C++" {
102106
int main(); // expected-warning {{'main' should not be 'extern "C++"'}}
103107
}
104108

105-
extern "C" {
106-
int main(); // expected-warning {{'main' should not be 'extern "C"'}}
107-
}
108-
109-
extern "C" int main(); // expected-warning {{'main' should not be 'extern "C"'}}
110109
extern "C++" int main(); // expected-warning {{'main' should not be 'extern "C++"'}}
111110

112111
namespace ns1 {
@@ -122,6 +121,21 @@ namespace ns2 {
122121
extern "C++" void main() {} // ok
123122
}
124123

124+
#elif TEST14
125+
extern "C" {
126+
int main(); // expected-warning {{'main' should not be 'extern "C"'}}
127+
}
128+
129+
extern "C" int main(); // expected-warning {{'main' should not be 'extern "C"'}}
130+
131+
#elif TEST15
132+
extern "C" __attribute__((visibility("default"))) __attribute__((weak))
133+
int main(); // expected-warning {{'main' should not be 'extern "C"'}}
134+
135+
unsigned long g() {
136+
return reinterpret_cast<unsigned long>(&main); // expected-warning {{referring to 'main' within an expression is a Clang extension}}
137+
}
138+
125139
#else
126140
#error Unknown Test
127141
#endif

0 commit comments

Comments
 (0)