aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Woehlke <matthew.woehlke@kitware.com>2014-04-16 10:02:21 -0400
committerJohn Ehresman <jpe@wingware.com>2014-04-16 20:59:54 +0200
commitebf3ba51187b6bb54cf819e5a0101c2f75e11de1 (patch)
tree531936f7d2240a151c5bd72774b247f6bc629700
parent35d006a7bf9b33807c1df93f5f9439ff83cd32c0 (diff)
Add parsing of 'noexcept' keyword
Teach Shiboken to parse the 'noexcept' keyword. This doesn't add any features (and we only support unconditional 'noexcept' for now), but addresses an internal error that causes shiboken to SEGV trying to parse modern versions of boost::intrusive_ptr. A test case to replicate the crash (without the other changes) is also added. Change-Id: I4713593dfd189c02ef4a2d7447d785b6d378019c Reviewed-by: John Ehresman <jpe@wingware.com>
-rw-r--r--ApiExtractor/parser/lexer.cpp13
-rw-r--r--ApiExtractor/parser/parser.cpp9
-rw-r--r--ApiExtractor/parser/parser.h1
-rw-r--r--ApiExtractor/parser/tokens.cpp1
-rw-r--r--ApiExtractor/parser/tokens.h1
-rw-r--r--tests/libsample/photon.h32
6 files changed, 57 insertions, 0 deletions
diff --git a/ApiExtractor/parser/lexer.cpp b/ApiExtractor/parser/lexer.cpp
index 0d1269e..eff54b7 100644
--- a/ApiExtractor/parser/lexer.cpp
+++ b/ApiExtractor/parser/lexer.cpp
@@ -1387,6 +1387,19 @@ void Lexer::scanKeyword8()
}
break;
+ case 'n':
+ if (*(cursor + 1) == 'o' &&
+ *(cursor + 2) == 'e' &&
+ *(cursor + 3) == 'x' &&
+ *(cursor + 4) == 'c' &&
+ *(cursor + 5) == 'e' &&
+ *(cursor + 6) == 'p' &&
+ *(cursor + 7) == 't') {
+ token_stream[(int) index++].kind = Token_noexcept;
+ return;
+ }
+ break;
+
case 'o':
if (*(cursor + 1) == 'p' &&
*(cursor + 2) == 'e' &&
diff --git a/ApiExtractor/parser/parser.cpp b/ApiExtractor/parser/parser.cpp
index c56369c..c49785f 100644
--- a/ApiExtractor/parser/parser.cpp
+++ b/ApiExtractor/parser/parser.cpp
@@ -1124,6 +1124,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node)
token_stream.nextToken(); // skip ')'
parseCvQualify(ast->fun_cv);
+ parseNoExcept();
parseExceptionSpecification(ast->exception_spec);
if (token_stream.lookAhead() == Token___attribute__)
@@ -1863,6 +1864,14 @@ bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node)
return false;
}
+bool Parser::parseNoExcept()
+{
+ // right now we only accept 'noexcept' with no conditional
+ CHECK(Token_noexcept);
+
+ return true;
+}
+
bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
{
std::size_t start = token_stream.cursor();
diff --git a/ApiExtractor/parser/parser.h b/ApiExtractor/parser/parser.h
index 8f31c13..af3c221 100644
--- a/ApiExtractor/parser/parser.h
+++ b/ApiExtractor/parser/parser.h
@@ -119,6 +119,7 @@ public:
bool parseNewExpression(ExpressionAST *&node);
bool parseNewInitializer(NewInitializerAST *&node);
bool parseNewTypeId(NewTypeIdAST *&node);
+ bool parseNoExcept();
bool parseOperator(OperatorAST *&node);
bool parseOperatorFunctionId(OperatorFunctionIdAST *&node);
bool parseParameterDeclaration(ParameterDeclarationAST *&node);
diff --git a/ApiExtractor/parser/tokens.cpp b/ApiExtractor/parser/tokens.cpp
index e3008de..34737d1 100644
--- a/ApiExtractor/parser/tokens.cpp
+++ b/ApiExtractor/parser/tokens.cpp
@@ -86,6 +86,7 @@ static char const * const _S_token_names[] = {
"mutable",
"namespace",
"new",
+ "noexcept",
"not",
"not_eq",
"number_literal",
diff --git a/ApiExtractor/parser/tokens.h b/ApiExtractor/parser/tokens.h
index dbe612d..20c17a7 100644
--- a/ApiExtractor/parser/tokens.h
+++ b/ApiExtractor/parser/tokens.h
@@ -87,6 +87,7 @@ enum TOKEN_KIND {
Token_mutable,
Token_namespace,
Token_new,
+ Token_noexcept,
Token_not,
Token_not_eq,
Token_number_literal,
diff --git a/tests/libsample/photon.h b/tests/libsample/photon.h
index 18917e2..1f8483e 100644
--- a/tests/libsample/photon.h
+++ b/tests/libsample/photon.h
@@ -96,6 +96,38 @@ LIBSAMPLE_API int callCalculateForValueDuplicatorReference(ValueDuplicator& valu
LIBSAMPLE_API int countValueIdentities(const std::list<ValueIdentity>& values);
LIBSAMPLE_API int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> >& values);
+// This simulates an internal error (SEGV) caused by 'noexcept' in
+// boost::intrusive_ptr before support for 'noexcept' was added. The ENTIRE
+// code below is needed to trigger the exception; it isn't seen with just a
+// 'noexcept' following a declaration.
+//
+// NOTE: For reasons that should be fairly obvious, this test unfortunately can
+// only be "run" when building in C++11 mode.
+#if __cplusplus < 201103L
+#define noexcept
+#endif
+class Pointer
+{
+public:
+ Pointer() noexcept : px(0) {}
+ Pointer(int* p) : px(p) {}
+
+ void reset() noexcept { Pointer().swap(*this); }
+
+ int* get() const noexcept { return px; }
+ int& operator*() const { return *px; }
+
+ void swap(Pointer& rhs) noexcept
+ {
+ int* tmp = px;
+ px = rhs.px;
+ rhs.px = tmp;
+ }
+
+private:
+ int* px;
+};
+
} // namespace Photon
#endif // PHOTON_H