diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index a7a1c662..b140b907 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -51,7 +51,7 @@ jobs: matrix: compiler: [{cc: gcc, cxx: g++}] cmake_build_type: [Debug] - flags: ['-fsanitize=address', '-fsanitize=thread'] + flags: ['-fsanitize=address', '-fsanitize=thread', '-fsanitize=undefined'] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: lukka/get-cmake@983956e4a5edce90f0dfcc38c1543077e668402b # v3.30.0 @@ -82,8 +82,12 @@ jobs: - name: Install run: cmake --install build --prefix build/install - name: Test + env: + UBSAN_OPTIONS: 'halt_on_error=1:print_stacktrace=1' run: ctest --output-on-failure --test-dir build - name: Test (standalone) + env: + UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 run: cd Test && ./runtests # Ensure we can compile/run on an older distro diff --git a/glslang/HLSL/hlslParseHelper.cpp b/glslang/HLSL/hlslParseHelper.cpp index 0fd724d0..c7a40f3b 100644 --- a/glslang/HLSL/hlslParseHelper.cpp +++ b/glslang/HLSL/hlslParseHelper.cpp @@ -6059,7 +6059,7 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn unaryArg = callNode.getAsUnaryNode()->getOperand(); arg0 = unaryArg; } - const TIntermSequence& aggArgs = *argp; // only valid when unaryArg is nullptr + const TIntermSequence& aggArgs = argp ? *argp : TIntermSequence(); // only valid when unaryArg is nullptr switch (callNode.getOp()) { case EOpTextureGather: diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 1f96129b..7a9fb2ed 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -507,7 +507,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EbtUint8: newConstArray[i].setU8Const(static_cast(-static_cast(unionArray[i].getU8Const()))); break; case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break; case EbtUint16:newConstArray[i].setU16Const(static_cast(-static_cast(unionArray[i].getU16Const()))); break; - case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; + case EbtInt64: { + int64_t i64val = unionArray[i].getI64Const(); + newConstArray[i].setI64Const(i64val == INT64_MIN ? INT64_MIN : -i64val); + break; + } case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; default: return nullptr; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 2a24cdaf..31b13f16 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -99,7 +99,8 @@ private: // A "call" is a pair: . // There can be duplicates. General assumption is the list is small. struct TCall { - TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { } + TCall(const TString& pCaller, const TString& pCallee) + : caller(pCaller), callee(pCallee), visited(false), currentPath(false), errorGiven(false) { } TString caller; TString callee; bool visited; diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 5f18c4e9..56f1f0b3 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -374,7 +374,7 @@ namespace { int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; } int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; } int op_pos(int a) { return a; } - int op_neg(int a) { return -a; } + int op_neg(int a) { return a == INT_MIN ? INT_MIN : -a; } int op_cmpl(int a) { return ~a; } int op_not(int a) { return !a; }