r288438 - [libclang] Add APIs to check the result of an integer expression in CXEvalResult without overflow
Argyrios Kyrtzidis via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 1 15:41:28 PST 2016
Author: akirtzidis
Date: Thu Dec 1 17:41:27 2016
New Revision: 288438
URL: http://llvm.org/viewvc/llvm-project?rev=288438&view=rev
Log:
[libclang] Add APIs to check the result of an integer expression in CXEvalResult without overflow
Patch by Emilio Cobos Álvarez!
See https://reviews.llvm.org/D26788
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/test/Index/evaluate-cursor.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/tools/libclang/libclang.exports
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=288438&r1=288437&r2=288438&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Dec 1 17:41:27 2016
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 36
+#define CINDEX_VERSION_MINOR 37
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -5266,6 +5266,25 @@ CINDEX_LINKAGE CXEvalResultKind clang_Ev
CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
/**
+ * \brief Returns the evaluation result as a long long integer if the
+ * kind is Int. This prevents overflows that may happen if the result is
+ * returned with clang_EvalResult_getAsInt.
+ */
+CINDEX_LINKAGE long long clang_EvalResult_getAsLongLong(CXEvalResult E);
+
+/**
+ * \brief Returns a non-zero value if the kind is Int and the evaluation
+ * result resulted in an unsigned integer.
+ */
+CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E);
+
+/**
+ * \brief Returns the evaluation result as an unsigned integer if
+ * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero.
+ */
+CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E);
+
+/**
* \brief Returns the evaluation result as double if the
* kind is double.
*/
Modified: cfe/trunk/test/Index/evaluate-cursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/evaluate-cursor.cpp?rev=288438&r1=288437&r2=288438&view=diff
==============================================================================
--- cfe/trunk/test/Index/evaluate-cursor.cpp (original)
+++ cfe/trunk/test/Index/evaluate-cursor.cpp Thu Dec 1 17:41:27 2016
@@ -15,6 +15,12 @@ void goo() {
int a = __LINE__;
}
+unsigned long long foo_int = 1ull << 60;
+
+unsigned long long HUGE = 1ull << 63;
+
+long long HUGE_NEG = -(1ll << 35);
+
// RUN: c-index-test -evaluate-cursor-at=%s:4:7 \
// RUN: -evaluate-cursor-at=%s:8:7 \
// RUN: -evaluate-cursor-at=%s:8:11 -std=c++11 %s | FileCheck %s
@@ -28,3 +34,11 @@ void goo() {
// CHECK-MACRO: [function macro]
// CHECK-MACRO: [function macro]
// CHECK-MACRO: [builtin macro]
+
+// RUN: c-index-test -evaluate-cursor-at=%s:18:20 \
+// RUN: -evaluate-cursor-at=%s:20:20 \
+// RUN: -evaluate-cursor-at=%s:22:11 \
+// RUN: -std=c++11 %s | FileCheck -check-prefix=CHECK-LONG %s
+// CHECK-LONG: unsigned, Value: 1152921504606846976
+// CHECK-LONG: unsigned, Value: 9223372036854775808
+// CHECK-LONG: Value: -34359738368
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=288438&r1=288437&r2=288438&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Thu Dec 1 17:41:27 2016
@@ -2462,8 +2462,14 @@ static void display_evaluate_results(CXE
switch (clang_EvalResult_getKind(result)) {
case CXEval_Int:
{
- int val = clang_EvalResult_getAsInt(result);
- printf("Kind: Int , Value: %d", val);
+ printf("Kind: Int, ");
+ if (clang_EvalResult_isUnsignedInt(result)) {
+ unsigned long long val = clang_EvalResult_getAsUnsigned(result);
+ printf("unsigned, Value: %llu", val);
+ } else {
+ long long val = clang_EvalResult_getAsLongLong(result);
+ printf("Value: %lld", val);
+ }
break;
}
case CXEval_Float:
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=288438&r1=288437&r2=288438&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Dec 1 17:41:27 2016
@@ -3518,10 +3518,12 @@ static StringLiteral* getCFSTR_value(Cal
struct ExprEvalResult {
CXEvalResultKind EvalType;
union {
- int intVal;
+ unsigned long long unsignedVal;
+ long long intVal;
double floatVal;
char *stringVal;
} EvalData;
+ bool IsUnsignedInt;
~ExprEvalResult() {
if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
EvalType != CXEval_Int) {
@@ -3542,10 +3544,32 @@ CXEvalResultKind clang_EvalResult_getKin
}
int clang_EvalResult_getAsInt(CXEvalResult E) {
+ return clang_EvalResult_getAsLongLong(E);
+}
+
+long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
if (!E) {
return 0;
}
- return ((ExprEvalResult *)E)->EvalData.intVal;
+ ExprEvalResult *Result = (ExprEvalResult*)E;
+ if (Result->IsUnsignedInt)
+ return Result->EvalData.unsignedVal;
+ return Result->EvalData.intVal;
+}
+
+unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
+ return ((ExprEvalResult *)E)->IsUnsignedInt;
+}
+
+unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
+ if (!E) {
+ return 0;
+ }
+
+ ExprEvalResult *Result = (ExprEvalResult*)E;
+ if (Result->IsUnsignedInt)
+ return Result->EvalData.unsignedVal;
+ return Result->EvalData.intVal;
}
double clang_EvalResult_getAsDouble(CXEvalResult E) {
@@ -3576,10 +3600,19 @@ static const ExprEvalResult* evaluateExp
CallExpr *callExpr;
auto result = llvm::make_unique<ExprEvalResult>();
result->EvalType = CXEval_UnExposed;
+ result->IsUnsignedInt = false;
if (ER.Val.isInt()) {
result->EvalType = CXEval_Int;
- result->EvalData.intVal = ER.Val.getInt().getExtValue();
+
+ auto& val = ER.Val.getInt();
+ if (val.isUnsigned()) {
+ result->IsUnsignedInt = true;
+ result->EvalData.unsignedVal = val.getZExtValue();
+ } else {
+ result->EvalData.intVal = val.getExtValue();
+ }
+
return result.release();
}
Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=288438&r1=288437&r2=288438&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Thu Dec 1 17:41:27 2016
@@ -335,6 +335,9 @@ clang_Cursor_hasAttrs
clang_Cursor_Evaluate
clang_EvalResult_getKind
clang_EvalResult_getAsInt
+clang_EvalResult_getAsLongLong
+clang_EvalResult_getAsUnsigned
+clang_EvalResult_isUnsignedInt
clang_EvalResult_getAsDouble
clang_EvalResult_getAsStr
clang_EvalResult_dispose
More information about the cfe-commits
mailing list