[clang] 179f4ba - Don't treat a CXXScopeSpec with a nested name specifier but no location
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 3 20:21:02 PDT 2020
Author: Richard Smith
Date: 2020-04-03T20:20:48-07:00
New Revision: 179f4baba0672a5e85c5db91095c4cd701a2d32d
URL: https://github.com/llvm/llvm-project/commit/179f4baba0672a5e85c5db91095c4cd701a2d32d
DIFF: https://github.com/llvm/llvm-project/commit/179f4baba0672a5e85c5db91095c4cd701a2d32d.diff
LOG: Don't treat a CXXScopeSpec with a nested name specifier but no location
as invalid.
We create those when forming trivial type source information with no
associated location, which, unfortunately, we do create in some cases
(when a TreeTransform with no base location is used to transform a
QualType).
This would previously lead to rejects-valid bugs when we misinterpreted
these constructs as having no nested-name-specifier.
Added:
Modified:
clang/include/clang/Sema/DeclSpec.h
clang/test/SemaCXX/nested-name-spec.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 78010b7bb46e..0e95e237e974 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -186,14 +186,14 @@ class CXXScopeSpec {
SourceLocation getLastQualifierNameLoc() const;
/// No scope specifier.
- bool isEmpty() const { return !Range.isValid(); }
+ bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; }
/// A scope specifier is present, but may be valid or invalid.
bool isNotEmpty() const { return !isEmpty(); }
/// An error occurred during parsing of the scope specifier.
- bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; }
+ bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; }
/// A scope specifier is present, and it refers to a real scope.
- bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; }
+ bool isValid() const { return getScopeRep() != nullptr; }
/// Indicate that this nested-name-specifier is invalid.
void SetInvalid(SourceRange R) {
diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp
index 725ac64cedb7..403bf1c0d4aa 100644
--- a/clang/test/SemaCXX/nested-name-spec.cpp
+++ b/clang/test/SemaCXX/nested-name-spec.cpp
@@ -460,3 +460,16 @@ class B {
};
}
}
+
+namespace DependentTemplateInTrivialNNSLoc {
+ // This testcase causes us to create trivial type source info when doing
+ // substitution into T::template g<>. That trivial type source info contained
+ // a NestedNameSpecifierLoc with no location information.
+ //
+ // Previously, creating a CXXScopeSpec from that resulted in an invalid scope
+ // spec, leading to crashes. Ensure we don't crash here.
+ template <typename T> void f(T &x) {
+ for (typename T::template g<> i : x) {} // expected-warning 0-1{{extension}}
+ x: goto x;
+ }
+}
More information about the cfe-commits
mailing list