Split Exception.cpp into a part that does and does not need RTTI.

ROOT needs to dynamic_cast a std::exception to an InterpreterException - that only works if the latter has rtti.
This commit is contained in:
Axel Naumann 2016-04-11 12:08:04 +02:00 committed by sftnight
parent 177ac81d74
commit ea41f5b87e
4 changed files with 59 additions and 46 deletions

View File

@ -43,6 +43,7 @@ add_cling_library(clingInterpreter
RequiredSymbols.cpp
ValueExtractionSynthesizer.cpp
Exception.cpp
ExceptionRTTI.cpp
Transaction.cpp
ASTTransformer.cpp
TransactionUnloader.cpp
@ -58,7 +59,7 @@ add_cling_library(clingInterpreter
add_dependencies(clingInterpreter clangBasic clangAST)
if(NOT WIN32)
set_source_files_properties(Exception.cpp COMPILE_FLAGS -fexceptions)
set_source_files_properties(ExceptionRTTI.cpp COMPILE_FLAGS "-fexceptions -frtti")
endif()
#set_source_files_properties(Exception.cpp COMPILE_FLAGS " /EHsc ")

View File

@ -10,59 +10,15 @@
#include "cling/Interpreter/Exception.h"
#include "cling/Utils/Validation.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/AST/ASTContext.h"
extern "C" {
///\param Arg: Take const void* and return void* to reduce the complexity in the
/// calling AST nodes, at the expense of possibly doing a
/// T* -> const void* -> const_cast<void*> -> T* round trip.
///\param Expr: The Expression to be checked for validity.
///\param Sema: The Sema for the context.
void* cling_runtime_internal_throwIfInvalidPointer(void* Sema, void* Expr,
const void* Arg) {
clang::Sema* S = (clang::Sema*)Sema;
clang::Expr* E = (clang::Expr*)Expr;
// The isValidAddress function return true even when the pointer is
// null thus the checks have to be done before returning successfully from the
// function in this specific order.
if (!Arg)
throw cling::InvalidDerefException(S, E,
cling::InvalidDerefException::DerefType::NULL_DEREF);
else if (!cling::utils::isAddressValid(Arg))
throw cling::InvalidDerefException(S, E,
cling::InvalidDerefException::DerefType::INVALID_MEM);
return const_cast<void*>(Arg);
}
}
namespace cling {
// Pin vtable
InterpreterException::~InterpreterException() {}
const char* InterpreterException::what() const throw() {
return "runtime_exception\n";
}
InvalidDerefException::InvalidDerefException(clang::Sema* S, clang::Expr* E,
cling::InvalidDerefException::DerefType type)
: m_Sema(S), m_Arg(E), m_Diags(&m_Sema->getDiagnostics()), m_Type(type) {}
InvalidDerefException::~InvalidDerefException() {}
const char* InvalidDerefException::what() const throw() {
// Invalid memory access.
if (m_Type == cling::InvalidDerefException::DerefType::INVALID_MEM)
return "Trying to access a pointer that points to an invalid memory address.";
// Null deref.
else
return "Trying to dereference null pointer or trying to call routine taking non-null arguments";
}
void InvalidDerefException::diagnose() const {
// Construct custom diagnostic: warning for invalid memory address;
// no equivalent in clang.

View File

@ -0,0 +1,56 @@
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Baozeng Ding <sploving1@gmail.com>
// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#include "cling/Interpreter/Exception.h"
#include "cling/Utils/Validation.h"
extern "C" {
///\param Arg: Take const void* and return void* to reduce the complexity in the
/// calling AST nodes, at the expense of possibly doing a
/// T* -> const void* -> const_cast<void*> -> T* round trip.
///\param Expr: The Expression to be checked for validity.
///\param Sema: The Sema for the context.
void* cling_runtime_internal_throwIfInvalidPointer(void* Sema, void* Expr,
const void* Arg) {
clang::Sema* S = (clang::Sema*)Sema;
clang::Expr* E = (clang::Expr*)Expr;
// The isValidAddress function return true even when the pointer is
// null thus the checks have to be done before returning successfully from the
// function in this specific order.
if (!Arg)
throw cling::InvalidDerefException(S, E,
cling::InvalidDerefException::DerefType::NULL_DEREF);
else if (!cling::utils::isAddressValid(Arg))
throw cling::InvalidDerefException(S, E,
cling::InvalidDerefException::DerefType::INVALID_MEM);
return const_cast<void*>(Arg);
}
}
namespace cling {
// Pin vtable
InterpreterException::~InterpreterException() {}
const char* InterpreterException::what() const throw() {
return "runtime_exception\n";
}
InvalidDerefException::~InvalidDerefException() {}
const char* InvalidDerefException::what() const throw() {
// Invalid memory access.
if (m_Type == cling::InvalidDerefException::DerefType::INVALID_MEM)
return "Trying to access a pointer that points to an invalid memory address.";
// Null deref.
else
return "Trying to dereference null pointer or trying to call routine taking non-null arguments";
}
} // end namespace cling

View File

@ -34,7 +34,7 @@ $(ObjRootDir)/cling-compiledata.h: FORCE
@diff -q $@_tmp $@ > /dev/null 2>&1 || mv $@_tmp $@
@rm -f $@_tmp
$(ObjRootDir)/Exception.o: CXX.Flags := $(subst -fno-exceptions,,$(CXX.Flags))
$(ObjRootDir)/ExceptionRTTI.o: CXX.Flags := $(subst -fno-rtti,,$(subst -fno-exceptions,,$(CXX.Flags)))
$(ObjRootDir)/CIFactory.o: $(ObjRootDir)/cling-compiledata.h
$(ObjRootDir)/CIFactory.o: CXX.Flags += -I$(ObjRootDir) -pthread
$(ObjRootDir)/Interpreter.o: $(ObjRootDir)/cling-compiledata.h