CI/Build - Enable -Werror on GCC/Clang (#1209)

- Inject `-Werror` (plus select warning toggles) into the shared GitHub Action used for configuring Linux/macOS builds.
- Replace several `0` / `CopyFromParent`-style null constants with `nullptr` to satisfy `-Wzero-as-null-pointer-constant`.
- Add defensive bounds/clamps and initialization to avoid fixed-buffer overreads/memcpy/sort issues and uninitialized reads.
This commit is contained in:
JIJINBEI
2026-04-29 05:42:31 +09:00
committed by GitHub
parent 4d64ddc666
commit 9255ff687a
16 changed files with 50 additions and 36 deletions

View File

@@ -152,6 +152,7 @@ runs:
cmake -G "Unix Makefiles" \
-D CMAKE_C_COMPILER=${{ inputs.compiler == 'clang' && 'clang' || 'gcc' }} \
-D CMAKE_CXX_COMPILER=${{ inputs.compiler == 'clang' && 'clang++' || 'g++' }} \
-D CMAKE_CXX_FLAGS="-Werror -Wzero-as-null-pointer-constant -Wno-unknown-warning-option -Wno-error=array-bounds -Wno-error=maybe-uninitialized -Wno-error=stringop-overflow -Wno-deprecated-declarations -Wno-error=cast-function-type-mismatch" \
-D BUILD_USE_PCH=${{ inputs.build-use-pch }} \
-D BUILD_OPT_PROFILE=${{ inputs.build-opt-profile }} \
-D BUILD_INCLUDE_SYMLINK=ON \
@@ -167,7 +168,6 @@ runs:
-D BUILD_GTEST=ON \
-D BUILD_CPP_STANDARD=C++17 \
-D INSTALL_GTEST=ON \
-D CMAKE_CXX_FLAGS="-Werror -Wall -Wextra -Wno-deprecated-declarations -Wno-unknown-warning-option -Wno-error=cast-function-type-mismatch" \
${{ inputs.additional-cmake-flags }} ..
echo "Configuration completed successfully for macOS"
shell: bash
@@ -183,6 +183,7 @@ runs:
cmake -G "Unix Makefiles" \
-D CMAKE_C_COMPILER=${{ inputs.compiler == 'clang' && 'clang' || 'gcc' }} \
-D CMAKE_CXX_COMPILER=${{ inputs.compiler == 'clang' && 'clang++' || 'g++' }} \
-D CMAKE_CXX_FLAGS="-Werror -Wzero-as-null-pointer-constant -Wno-unknown-warning-option -Wno-error=array-bounds -Wno-error=maybe-uninitialized -Wno-error=stringop-overflow" \
-D BUILD_USE_PCH=${{ inputs.build-use-pch }} \
-D BUILD_INCLUDE_SYMLINK=ON \
-D BUILD_OPT_PROFILE=${{ inputs.build-opt-profile }} \

View File

@@ -117,7 +117,7 @@ private:
name::Persistence_ name::myPersistence_; \
occ::handle<TObj_Object> name::Persistence_::New(const TDF_Label& aLabel) const \
{ \
return new name((const TObj_Persistence*)0, aLabel); \
return new name(static_cast<const TObj_Persistence*>(nullptr), aLabel); \
}
#endif

View File

@@ -304,7 +304,7 @@ void IGESData_IGESWriter::DirPart(const occ::handle<IGESData_IGESEntity>& anent)
if (anent->HasShortLabel())
{
occ::handle<TCollection_HAsciiString> slab = anent->ShortLabel();
for (i = 0; i < slab->Length(); i++)
for (i = 0; i < slab->Length() && i < 8; i++)
label[i] = slab->Value(i + 1);
}
if (anent->HasSubScriptNumber())

View File

@@ -101,7 +101,7 @@ StepData_EnumTool::StepData_EnumTool(const char* const e0,
void StepData_EnumTool::AddDefinition(const char* const term)
{
char text[80];
char text[80] = {0};
if (!term)
return;
if (term[0] == '\0')

View File

@@ -23,7 +23,8 @@
#include <Standard_CStringHasher.hxx>
#include <VrmlData_ErrorStatus.hxx>
#define VRMLDATA_LCOMPARE(aa, bb) ((strncmp(aa, bb, sizeof(bb) - 1)) ? 0L : (aa += sizeof(bb) - 1))
#define VRMLDATA_LCOMPARE(aa, bb) \
((strncmp(aa, bb, sizeof(bb) - 1)) ? nullptr : (aa += sizeof(bb) - 1))
struct VrmlData_InBuffer;
class VrmlData_Scene;

View File

@@ -348,7 +348,8 @@ inline TrigResult Trigonometric(double theA,
return aResult;
}
aNZer = aPoly.NbRoots;
// NbRoots is bounded by the fixed storage capacity; clamp defensively.
aNZer = std::min<size_t>(aPoly.NbRoots, aZer.size());
for (size_t i = 0; i < aNZer; ++i)
{
aZer[i] = aPoly.Roots[i];

View File

@@ -360,7 +360,9 @@ void Poly_MergeNodesTool::PushLastElement(int theNbNodes)
if (myToMergeElems)
{
NCollection_Vec4<int> aSorted = myNodeInds;
std::sort(aSorted.ChangeData(), aSorted.ChangeData() + theNbNodes);
// theNbNodes is bounded by the Vec4 capacity; clamp defensively.
const int aNbToSort = std::min(theNbNodes, 4);
std::sort(aSorted.ChangeData(), aSorted.ChangeData() + aNbToSort);
if (!myElemMap.Add(aSorted))
{
++myNbMergedElems;

View File

@@ -81,7 +81,7 @@ extern "C++"
return yylex();
}
int yylex(std::istream* new_in, std::ostream* new_out = 0)
int yylex(std::istream* new_in, std::ostream* new_out = nullptr)
{
switch_streams(new_in, new_out);
return yylex();
@@ -122,7 +122,7 @@ extern "C++"
// arg_yyin and arg_yyout default to the cin and cout, but we
// only make that assignment when initializing in yylex().
yyFlexLexer(std::istream& arg_yyin, std::ostream& arg_yyout);
yyFlexLexer(std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0);
yyFlexLexer(std::istream* arg_yyin = nullptr, std::ostream* arg_yyout = nullptr);
private:
void ctor_common();
@@ -142,7 +142,7 @@ extern "C++"
virtual int yylex();
virtual void switch_streams(std::istream& new_in, std::ostream& new_out);
virtual void switch_streams(std::istream* new_in = 0, std::ostream* new_out = 0);
virtual void switch_streams(std::istream* new_in = nullptr, std::ostream* new_out = nullptr);
virtual int yywrap();
protected:

View File

@@ -218,7 +218,7 @@ void Message_PrinterOStream::SetConsoleTextColor(Standard_OStream* theOStream
return;
}
const char* aCode;
const char* aCode = "";
switch (theTextColor)
{
case Message_ConsoleColor_Default:

View File

@@ -180,15 +180,17 @@ public:
{
if (theOther.isInline())
{
// When the source is inline, mySize is bounded by MAX_ARRAY_SIZE.
const size_t aNb = std::min(mySize, static_cast<size_t>(MAX_ARRAY_SIZE));
if constexpr (IS_TRIVIAL)
{
std::memcpy(inlinePtr(), theOther.inlinePtr(), mySize * sizeof(theItem));
std::memcpy(inlinePtr(), theOther.inlinePtr(), aNb * sizeof(theItem));
}
else
{
for (size_t i = 0; i < mySize; ++i)
for (size_t i = 0; i < aNb; ++i)
new (inlinePtr() + i) theItem(std::move(theOther.inlinePtr()[i]));
for (size_t i = 0; i < mySize; ++i)
for (size_t i = 0; i < aNb; ++i)
theOther.inlinePtr()[i].~theItem();
}
}
@@ -212,7 +214,9 @@ public:
{
Deallocate();
myPtr = inlinePtr();
std::memcpy(inlinePtr(), theOther.inlinePtr(), mySize * sizeof(theItem));
// When the source is inline, mySize is bounded by MAX_ARRAY_SIZE.
const size_t aNb = std::min(mySize, static_cast<size_t>(MAX_ARRAY_SIZE));
std::memcpy(inlinePtr(), theOther.inlinePtr(), aNb * sizeof(theItem));
}
else if (!isInline())
{
@@ -240,9 +244,11 @@ public:
Standard::Free(myPtr);
myPtr = inlinePtr();
mySize = theOther.mySize;
for (size_t i = 0; i < mySize; ++i)
// When the source is inline, mySize is bounded by MAX_ARRAY_SIZE.
const size_t aNb = std::min(mySize, static_cast<size_t>(MAX_ARRAY_SIZE));
for (size_t i = 0; i < aNb; ++i)
new (inlinePtr() + i) theItem(std::move(theOther.inlinePtr()[i]));
for (size_t i = 0; i < mySize; ++i)
for (size_t i = 0; i < aNb; ++i)
theOther.inlinePtr()[i].~theItem();
}
else

View File

@@ -110,7 +110,7 @@ ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine& line,
const bool P2DOnFirst,
const int IndMin,
const int IndMax)
: PtrOnmySvSurfaces(0),
: PtrOnmySvSurfaces(nullptr),
myLine(line),
indicemin(std::min(IndMin, IndMax)),
indicemax(std::max(IndMin, IndMax)),

View File

@@ -68,11 +68,11 @@ struct IDelaBella
// it is treated as 2*sizeof coordinate type
virtual int Triangulate(int points,
const float* x,
const float* y = 0,
const float* y = nullptr,
int advance_bytes = 0) = 0;
virtual int Triangulate(int points,
const double* x,
const double* y = 0,
const double* y = nullptr,
int advance_bytes = 0) = 0;
// num of points passed to last call to Triangulate()

View File

@@ -278,7 +278,7 @@ public:
bool Init(EAGLContext* theGContext, const bool theIsCoreProfile = false)
{
return Init((Aspect_Drawable)0,
(Aspect_Display)0,
(Aspect_Display) nullptr,
(Aspect_RenderingContext)theGContext,
theIsCoreProfile);
}
@@ -288,7 +288,7 @@ public:
bool Init(NSOpenGLContext* theGContext, const bool theIsCoreProfile = false)
{
return Init((Aspect_Drawable)0,
(Aspect_Display)0,
(Aspect_Display) nullptr,
(Aspect_RenderingContext)theGContext,
theIsCoreProfile);
}

View File

@@ -76,7 +76,7 @@ void OpenGl_Window::Init (const occ::handle<OpenGl_GraphicDriver>& theDriver,
const occ::handle<OpenGl_Context>& theShareCtx)
{
myGlContext = new OpenGl_Context (theCaps);
myOwnGContext = (theGContext == 0);
myOwnGContext = (theGContext == nullptr);
myPlatformWindow = thePlatformWindow;
mySizeWindow = theSizeWindow;
#if defined(__APPLE__) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE

View File

@@ -75,18 +75,19 @@ Xw_Window::Xw_Window(const occ::handle<Aspect_DisplayConnection>& theXDisplay,
aWinAttr.border_pixel = 0;
aWinAttr.override_redirect = False;
myXWindow = (Window)XCreateWindow(aDisp,
aParent,
myXLeft,
myYTop,
thePxWidth,
thePxHeight,
0,
aVisInfo != nullptr ? aVisInfo->depth : CopyFromParent,
InputOutput,
aVisInfo != nullptr ? aVisInfo->visual : CopyFromParent,
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
&aWinAttr);
myXWindow =
(Window)XCreateWindow(aDisp,
aParent,
myXLeft,
myYTop,
thePxWidth,
thePxHeight,
0,
aVisInfo != nullptr ? aVisInfo->depth : CopyFromParent,
InputOutput,
aVisInfo != nullptr ? aVisInfo->visual : static_cast<Visual*>(nullptr),
CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
&aWinAttr);
if (myXWindow == 0)
{
throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window");

View File

@@ -244,7 +244,9 @@ bool SelectMgr_BaseIntersector::RayCylinderIntersection(const double theBottomR
return false;
}
std::sort(anIntersections, anIntersections + aNbIntersections);
// aNbIntersections is bounded by the fixed 4-element buffer; clamp defensively.
const int aNbToSort = std::min(aNbIntersections, 4);
std::sort(anIntersections, anIntersections + aNbToSort);
theTimeEnter = anIntersections[0];
if (aNbIntersections > 1)
{