From 146a534932b66af491f6cce014095a480d1790b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= <thorbjorn.lindeijer@nokia.com>
Date: Tue, 10 Feb 2009 17:20:47 +0100
Subject: [PATCH] Fixed all crashes due to refencing undefined types

Introduced UndefinedType class to replace null pointer.

Done with Roberto Raggi
---
 .../cplusplus/CPlusPlusForwardDeclarations.h  |  1 +
 src/shared/cplusplus/CheckSpecifier.cpp       | 24 ++++++++++---------
 src/shared/cplusplus/CoreTypes.h              | 17 +++++++++++++
 src/shared/cplusplus/FullySpecifiedType.cpp   | 10 +++++---
 src/shared/cplusplus/Type.cpp                 |  3 +++
 src/shared/cplusplus/Type.h                   |  1 +
 6 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
index 31b01bfd815..2909c0775ab 100644
--- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
+++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
@@ -108,6 +108,7 @@ class QualifiedNameId;
 class FullySpecifiedType;
 class TypeVisitor;
 class Type;
+class UndefinedType;
 class VoidType;
 class IntegerType;
 class FloatType;
diff --git a/src/shared/cplusplus/CheckSpecifier.cpp b/src/shared/cplusplus/CheckSpecifier.cpp
index 20a3662e7b8..fddfd525689 100644
--- a/src/shared/cplusplus/CheckSpecifier.cpp
+++ b/src/shared/cplusplus/CheckSpecifier.cpp
@@ -200,30 +200,30 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
             break;
 
         case T_CHAR:
-            if (_fullySpecifiedType.type())
+            if (_fullySpecifiedType)
                 translationUnit()->error(ast->specifier_token,
                                          "duplicate data type in declaration");
             _fullySpecifiedType.setType(control()->integerType(IntegerType::Char));
             break;
 
         case T_WCHAR_T:
-            if (_fullySpecifiedType.type())
+            if (_fullySpecifiedType)
                 translationUnit()->error(ast->specifier_token,
                                          "duplicate data type in declaration");
             _fullySpecifiedType.setType(control()->integerType(IntegerType::WideChar));
             break;
 
         case T_BOOL:
-            if (_fullySpecifiedType.type())
+            if (_fullySpecifiedType)
                 translationUnit()->error(ast->specifier_token,
                                          "duplicate data type in declaration");
             _fullySpecifiedType.setType(control()->integerType(IntegerType::Bool));
             break;
 
         case T_SHORT:
-            if (Type *tp = _fullySpecifiedType.type()) {
+            if (_fullySpecifiedType) {
                 IntegerType *intType = control()->integerType(IntegerType::Int);
-                if (tp != intType)
+                if (_fullySpecifiedType.type() != intType)
                     translationUnit()->error(ast->specifier_token,
                                              "duplicate data type in declaration");
             }
@@ -231,7 +231,8 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
             break;
 
         case T_INT:
-            if (Type *tp = _fullySpecifiedType.type()) {
+            if (_fullySpecifiedType) {
+                Type *tp = _fullySpecifiedType.type();
                 IntegerType *shortType = control()->integerType(IntegerType::Short);
                 IntegerType *longType = control()->integerType(IntegerType::Long);
                 IntegerType *longLongType = control()->integerType(IntegerType::LongLong);
@@ -244,7 +245,8 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
             break;
 
         case T_LONG:
-            if (Type *tp = _fullySpecifiedType.type()) {
+            if (_fullySpecifiedType) {
+                Type *tp = _fullySpecifiedType.type();
                 IntegerType *intType = control()->integerType(IntegerType::Int);
                 IntegerType *longType = control()->integerType(IntegerType::Long);
                 FloatType *doubleType = control()->floatType(FloatType::Double);
@@ -263,16 +265,16 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
             break;
 
         case T_FLOAT:
-            if (_fullySpecifiedType.type())
+            if (_fullySpecifiedType)
                 translationUnit()->error(ast->specifier_token,
                                          "duplicate data type in declaration");
             _fullySpecifiedType.setType(control()->floatType(FloatType::Float));
             break;
 
         case T_DOUBLE:
-            if (Type *tp = _fullySpecifiedType.type()) {
+            if (_fullySpecifiedType) {
                 IntegerType *longType = control()->integerType(IntegerType::Long);
-                if (tp == longType) {
+                if (_fullySpecifiedType.type() == longType) {
                     _fullySpecifiedType.setType(control()->floatType(FloatType::LongDouble));
                     break;
                 }
@@ -283,7 +285,7 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
             break;
 
         case T_VOID:
-            if (_fullySpecifiedType.type())
+            if (_fullySpecifiedType)
                 translationUnit()->error(ast->specifier_token,
                                          "duplicate data type in declaration");
             _fullySpecifiedType.setType(control()->voidType());
diff --git a/src/shared/cplusplus/CoreTypes.h b/src/shared/cplusplus/CoreTypes.h
index 42895f4dba3..f859fbf300b 100644
--- a/src/shared/cplusplus/CoreTypes.h
+++ b/src/shared/cplusplus/CoreTypes.h
@@ -61,6 +61,23 @@
 CPLUSPLUS_BEGIN_HEADER
 CPLUSPLUS_BEGIN_NAMESPACE
 
+class CPLUSPLUS_EXPORT UndefinedType : public Type
+{
+public:
+    static UndefinedType *instance()
+    {
+        static UndefinedType t;
+        return &t;
+    }
+
+    virtual bool isEqualTo(const Type *other) const
+    { return this == other; }
+
+protected:
+    virtual void accept0(TypeVisitor *)
+    { }
+};
+
 class CPLUSPLUS_EXPORT VoidType: public Type
 {
 public:
diff --git a/src/shared/cplusplus/FullySpecifiedType.cpp b/src/shared/cplusplus/FullySpecifiedType.cpp
index 71dec2934bc..0afcdd0d754 100644
--- a/src/shared/cplusplus/FullySpecifiedType.cpp
+++ b/src/shared/cplusplus/FullySpecifiedType.cpp
@@ -52,18 +52,22 @@
 
 #include "FullySpecifiedType.h"
 #include "Type.h"
+#include "CoreTypes.h"
 
 CPLUSPLUS_BEGIN_NAMESPACE
 
 FullySpecifiedType::FullySpecifiedType(Type *type) :
     _type(type), _flags(0)
-{ }
+{
+    if (! type)
+        _type = UndefinedType::instance();
+}
 
 FullySpecifiedType::~FullySpecifiedType()
 { }
 
 bool FullySpecifiedType::isValid() const
-{ return _type != 0; }
+{ return _type != UndefinedType::instance(); }
 
 Type *FullySpecifiedType::type() const
 { return _type; }
@@ -177,7 +181,7 @@ Type &FullySpecifiedType::operator*()
 { return *_type; }
 
 FullySpecifiedType::operator bool() const
-{ return _type != 0; }
+{ return _type != UndefinedType::instance(); }
 
 const Type &FullySpecifiedType::operator*() const
 { return *_type; }
diff --git a/src/shared/cplusplus/Type.cpp b/src/shared/cplusplus/Type.cpp
index 52d51b57bdb..b88b0afab48 100644
--- a/src/shared/cplusplus/Type.cpp
+++ b/src/shared/cplusplus/Type.cpp
@@ -63,6 +63,9 @@ Type::Type()
 Type::~Type()
 { }
 
+bool Type::isUndefinedType() const
+{ return this == UndefinedType::instance(); }
+
 bool Type::isVoidType() const
 { return asVoidType() != 0; }
 
diff --git a/src/shared/cplusplus/Type.h b/src/shared/cplusplus/Type.h
index dd22c982c24..320555b40cf 100644
--- a/src/shared/cplusplus/Type.h
+++ b/src/shared/cplusplus/Type.h
@@ -67,6 +67,7 @@ public:
     Type();
     virtual ~Type();
 
+    bool isUndefinedType() const;
     bool isVoidType() const;
     bool isIntegerType() const;
     bool isFloatType() const;
-- 
GitLab