Skip to content

Commit 437f280

Browse files
authored
fix: integer overflow in Complexity analysis (#2509)
* fix: integer overflow in Complexity analysis fixes #2508
1 parent e6cc668 commit 437f280

File tree

12 files changed

+99
-16
lines changed

12 files changed

+99
-16
lines changed

cmake/SouffleTests.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,9 @@ function(SOUFFLE_POSITIVE_MULTI_TEST)
388388
FACTS_DIR_NAME ${FACTS_DIR_NAME})
389389
endforeach()
390390
endfunction()
391+
392+
function(SOUFFLE_POSITIVE_FUNCTOR_TEST TEST_NAME)
393+
souffle_run_test_helper(TEST_NAME ${TEST_NAME} FUNCTORS ${ARGN})
394+
souffle_run_test_helper(TEST_NAME ${TEST_NAME} COMPILED FUNCTORS ${ARGN})
395+
souffle_run_test_helper(TEST_NAME ${TEST_NAME} COMPILED_SPLITTED FUNCTORS ${ARGN})
396+
endfunction()

src/ram/analysis/Complexity.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
namespace souffle::ram::analysis {
3131

32+
static const int MAX_COMPLEXITY = std::numeric_limits<int>::max();
33+
3234
int ComplexityAnalysis::getComplexity(const Node* node) const {
3335
// visitor
3436
class ValueComplexityVisitor : public Visitor<int> {
@@ -39,7 +41,12 @@ int ComplexityAnalysis::getComplexity(const Node* node) const {
3941

4042
// conjunction
4143
int visit_(type_identity<Conjunction>, const Conjunction& conj) override {
42-
return dispatch(conj.getLHS()) + dispatch(conj.getRHS());
44+
const int cl = dispatch(conj.getLHS());
45+
const int cr = dispatch(conj.getRHS());
46+
if (cl == MAX_COMPLEXITY || cr == MAX_COMPLEXITY) {
47+
return MAX_COMPLEXITY;
48+
}
49+
return cl + cr;
4350
}
4451

4552
// negation
@@ -58,11 +65,16 @@ int ComplexityAnalysis::getComplexity(const Node* node) const {
5865
}
5966

6067
int visit_(type_identity<Constraint>, const Constraint& c) override {
61-
return dispatch(c.getLHS()) + dispatch(c.getRHS());
68+
const int cl = dispatch(c.getLHS());
69+
const int cr = dispatch(c.getRHS());
70+
if (cl == MAX_COMPLEXITY || cr == MAX_COMPLEXITY) {
71+
return MAX_COMPLEXITY;
72+
}
73+
return cl + cr;
6274
}
6375

6476
int visit_(type_identity<UserDefinedOperator>, const UserDefinedOperator&) override {
65-
return std::numeric_limits<int>::max();
77+
return MAX_COMPLEXITY;
6678
}
6779

6880
// emptiness check
@@ -74,7 +86,13 @@ int ComplexityAnalysis::getComplexity(const Node* node) const {
7486
int visit_(type_identity<AbstractOperator>, const AbstractOperator& op) override {
7587
int exprComplexity = 0;
7688
for (auto* expr : op.getArguments()) {
77-
exprComplexity += dispatch(*expr);
89+
const int complexity = dispatch(*expr);
90+
if (complexity == MAX_COMPLEXITY) {
91+
exprComplexity = MAX_COMPLEXITY;
92+
break;
93+
} else {
94+
exprComplexity += dispatch(*expr);
95+
}
7896
}
7997
return exprComplexity;
8098
}

tests/evaluation/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,6 @@ positive_test(unsigned_operations)
168168
positive_test(unused_constraints)
169169
positive_test(x9)
170170
positive_test(issue2160)
171+
172+
add_subdirectory(issue2508)
173+
souffle_positive_functor_test(issue2508 CATEGORY evaluation)

tests/evaluation/issue2508/B.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
()

tests/evaluation/issue2508/C.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
()
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Souffle - A Datalog Compiler
2+
# Copyright (c) 2022 The Souffle Developers. All rights reserved
3+
# Licensed under the Universal Permissive License v 1.0 as shown at:
4+
# - https://opensource.org/licenses/UPL
5+
# - <souffle root>/licenses/SOUFFLE-UPL.txt
6+
7+
add_library(issue2508 SHARED functors.cpp)
8+
target_include_directories(issue2508 PRIVATE "${CMAKE_SOURCE_DIR}/src/include")
9+
10+
target_compile_features(issue2508
11+
PUBLIC cxx_std_17)
12+
13+
set_target_properties(issue2508 PROPERTIES CXX_EXTENSIONS OFF)
14+
set_target_properties(issue2508 PROPERTIES OUTPUT_NAME "functors")
15+
set_target_properties(issue2508 PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
16+
17+
if (WIN32)
18+
# Prefix all shared libraries with 'lib'.
19+
set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
20+
21+
# Prefix all static libraries with 'lib'.
22+
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
23+
endif ()
24+
25+
if (SOUFFLE_DOMAIN_64BIT)
26+
target_compile_definitions(issue2508
27+
PUBLIC RAM_DOMAIN_SIZE=64)
28+
endif()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "souffle/RecordTable.h"
2+
#include "souffle/SymbolTable.h"
3+
4+
extern "C" {
5+
6+
souffle::RamDomain id(
7+
souffle::SymbolTable* symbolTable, souffle::RecordTable* recordTable, souffle::RamDomain x) {
8+
return x;
9+
}
10+
11+
souffle::RamDomain decode(
12+
souffle::SymbolTable* symbolTable, souffle::RecordTable* recordTable, souffle::RamDomain x) {
13+
symbolTable->decode(x);
14+
return x;
15+
}
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.functor id(symbol): symbol stateful
2+
.functor decode(symbol): symbol stateful
3+
4+
.type T = C1 {A0 : symbol} | C2 {A0: number}
5+
6+
.decl A(A2: T)
7+
.decl B()
8+
.output B()
9+
.decl C()
10+
.output C()
11+
12+
A($C2(10000000)).
13+
A($C1("X")).
14+
A($C1("Y")).
15+
16+
B() :-
17+
A($C1(X)),
18+
(@decode(X) = @id("Y")).
19+
20+
C() :-
21+
A($C2(_)).
22+

tests/evaluation/issue2508/issue2508.err

Whitespace-only changes.

tests/evaluation/issue2508/issue2508.out

Whitespace-only changes.

0 commit comments

Comments
 (0)