[PATCH] Fix for crash due to g++.old-deja/g++.other/using3.C
Dinesh Dwivedi
dinesh.d at samsung.com
Wed Mar 12 00:37:22 PDT 2014
Hi rjmccall, rsmith,
Following patch fixes crash in clang with attached test case [taken from g++.old-deja/g++.other/using3.C].
Issue:
Test is trying to make using declaration for a non-existing member in base class in derived class and expect error
while compiling. Current clang code handles normal cases properly.
Problem arises when base class is typedefed to a type constructed in-place. As using declaration is referring to a
non-existing member, normal lookup fails and while trying typo-correction, clang returns typedef declaration as
possible alternative, which is not a record type and can not be type casted to EnumDecl/ RecordDecl/ CXXRecordDecl.
But Sema::CheckUsingShadowDecl() assumes otherwise and tries to typecast it to CXXRecordDecl without any check while
checking if referred type is from base class or not. This results in crash in clang.
Solution:
I looked for ways to get CXXRecordDecl from TypedefDecl but did not find any. I found function like getUnderlyingDecl()
but they just work with UsingDecls and ObjCCompatibleAliasDecls. Moreover, for any existing member, clang find proper
declaration and code works fine.
So I have added a check in Sema::CheckUsingShadowDecl() to bypass base class check if referred type in using declaration
is not in a record type. A proper fix will be if we can get proper RecordDecl from TypedefDecl and use it for this check
or handle TypedefDecl case separately.
http://llvm-reviews.chandlerc.com/D3051
Files:
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/using-decl-2.cpp
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -7164,28 +7164,29 @@
if (!getLangOpts().CPlusPlus11 && CurContext->isRecord()) {
DeclContext *OrigDC = Orig->getDeclContext();
- // Handle enums and anonymous structs.
+ if (OrigDC->isRecord()) {
+ // Handle enums and anonymous structs.
if (isa<EnumDecl>(OrigDC)) OrigDC = OrigDC->getParent();
- CXXRecordDecl *OrigRec = cast<CXXRecordDecl>(OrigDC);
- while (OrigRec->isAnonymousStructOrUnion())
- OrigRec = cast<CXXRecordDecl>(OrigRec->getDeclContext());
+ CXXRecordDecl *OrigRec = cast<CXXRecordDecl>(OrigDC);
+ while (OrigRec->isAnonymousStructOrUnion())
+ OrigRec = cast<CXXRecordDecl>(OrigRec->getDeclContext());
+
+ if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom(OrigRec)) {
+ if (OrigDC == CurContext) {
+ Diag(Using->getLocation(),
+ diag::err_using_decl_nested_name_specifier_is_current_class)
+ << Using->getQualifierLoc().getSourceRange();
+ Diag(Orig->getLocation(), diag::note_using_decl_target);
+ return true;
+ }
- if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom(OrigRec)) {
- if (OrigDC == CurContext) {
- Diag(Using->getLocation(),
- diag::err_using_decl_nested_name_specifier_is_current_class)
- << Using->getQualifierLoc().getSourceRange();
+ Diag(Using->getQualifierLoc().getBeginLoc(),
+ diag::err_using_decl_nested_name_specifier_is_not_base_class)
+ << Using->getQualifier() << cast<CXXRecordDecl>(CurContext)
+ << Using->getQualifierLoc().getSourceRange();
Diag(Orig->getLocation(), diag::note_using_decl_target);
return true;
}
-
- Diag(Using->getQualifierLoc().getBeginLoc(),
- diag::err_using_decl_nested_name_specifier_is_not_base_class)
- << Using->getQualifier()
- << cast<CXXRecordDecl>(CurContext)
- << Using->getQualifierLoc().getSourceRange();
- Diag(Orig->getLocation(), diag::note_using_decl_target);
- return true;
}
}
Index: test/SemaCXX/using-decl-2.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/using-decl-2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {
+ A();
+};
+
+typedef struct {
+ A i;
+} S; // expected-note {{declared here}}
+
+struct B : S {
+ using S::S; // expected-error {{no member named 'S' in 'S'}}
+};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3051.1.patch
Type: text/x-patch
Size: 2630 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140312/7f316d55/attachment.bin>
More information about the cfe-commits
mailing list