Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix -Wall warnings #579

Draft
wants to merge 37 commits into
base: master
Choose a base branch
from

Conversation

benoit-pierre
Copy link
Contributor

@benoit-pierre benoit-pierre commented Jul 20, 2024

Remaining:

|| In file included from thirdparty/kpvcrlib/crengine/crengine/include/lvstream.h:32,
|| In member function ‘void LVRef<T>::Release() [with T = ListNumberingProps]’,
inlined from ‘LVRef<T>::~LVRef() [with T = ListNumberingProps]’ at thirdparty/kpvcrlib/crengine/crengine/src/../include/lvref.h|426| 23,
inlined from ‘void ldomDocument::setNodeNumberingProps(lUInt32, ListNumberingPropsRef)’ at thirdparty/kpvcrlib/crengine/crengine/src/lvtinydom.cpp|20380| 14:
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*MEM[(const struct LVRef *)v_4(D)]._ptr.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]
||   377 |         if (--_ptr->_refcount == 0) // NOLINT(clang-analyzer-cplusplus.NewDelete)
||       |               ~~~~~~^~~~~~~~~
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*MEM[(const struct LVRef *)v_4(D)]._ptr.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]
||       | [crengine  12%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvstream.cpp.o
||       | [crengine  13%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvxml.cpp.o
||       | [crengine  14%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/chmfmt.cpp.o
||       | [crengine  15%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/epubfmt.cpp.o
||       | [crengine  16%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/pdbfmt.cpp.o
||       | [crengine  17%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/wordfmt.cpp.o
||       | [crengine  18%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvopc.cpp.o
||       | [crengine  19%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/docxfmt.cpp.o
||       | [crengine  20%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/odtfmt.cpp.o
||       | [crengine  21%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/odxutil.cpp.o
||       | [crengine  23%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/fb3fmt.cpp.o
||       | [crengine  24%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvstsheet.cpp.o
|| In file included from thirdparty/kpvcrlib/crengine/crengine/include/cssdef.h:20,
|| In member function ‘T* LVRef<T>::operator->() const [with T = LVCssDeclaration]’,
inlined from ‘bool LVStyleSheet::parseAndAdvance(const char*&, bool, lString32)’ at thirdparty/kpvcrlib/crengine/crengine/src/lvstsheet.cpp|7040| 47:
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|480 col 70| warning: ‘*(ref_count_rec_t*)<unknown>.ref_count_rec_t::_obj’ may be used uninitialized [-Wmaybe-uninitialized]
||   480 |     T * operator -> () const { return reinterpret_cast<T*>(_ptr->_obj); } // NOLINT(clang-analyzer-cplusplus.NewDelete)
||       |                                                                      ^
|| In member function ‘void LVRef<T>::Release() [with T = LVCssDeclaration]’,
inlined from ‘LVRef<T>::~LVRef() [with T = LVCssDeclaration]’ at thirdparty/kpvcrlib/crengine/crengine/src/../include/lvref.h|426| 23,
inlined from ‘bool LVStyleSheet::parseAndAdvance(const char*&, bool, lString32)’ at thirdparty/kpvcrlib/crengine/crengine/src/lvstsheet.cpp|7050| 9:
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*(ref_count_rec_t*)<unknown>.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]
||   377 |         if (--_ptr->_refcount == 0) // NOLINT(clang-analyzer-cplusplus.NewDelete)
||       |               ~~~~~~^~~~~~~~~
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*(ref_count_rec_t*)<unknown>.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]
||       | [crengine  25%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/txtselector.cpp.o
||       | [crengine  26%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvfnt.cpp.o
||       | [crengine  27%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/hyphman.cpp.o
||       | [crengine  28%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/textlang.cpp.o
||       | [crengine  29%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvfntman.cpp.o
||       | [crengine  30%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvimg.cpp.o
||       | [crengine  31%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvdrawbuf.cpp.o
||       | [crengine  32%] Building CXX object CMakeFiles/crengine.dir/crengine/crengine/src/lvdocview.cpp.o
|| In file included from thirdparty/kpvcrlib/crengine/crengine/include/cssdef.h:20,
|| In member function ‘void LVRef<T>::Release() [with T = LVThread]’,
inlined from ‘LVRef<T>::~LVRef() [with T = LVThread]’ at thirdparty/kpvcrlib/crengine/crengine/src/../include/lvref.h|426| 23,
inlined from ‘void LVDocView::cachePageImage(int)’ at thirdparty/kpvcrlib/crengine/crengine/src/lvdocview.cpp|799| 1:
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*(ref_count_rec_t*)<unknown>.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]
||   377 |         if (--_ptr->_refcount == 0) // NOLINT(clang-analyzer-cplusplus.NewDelete)
||       |               ~~~~~~^~~~~~~~~
thirdparty/kpvcrlib/crengine/crengine/include/lvref.h|377 col 21| warning: ‘*(ref_count_rec_t*)<unknown>.ref_count_rec_t::_refcount’ may be used uninitialized [-Wmaybe-uninitialized]

This code is pretty hairy… Interestingly, those warnings go away when disabling crengine's custom memory manager (-DLDOM_USE_OWN_MEM_MAN=0).


This change is Reviewable

@poire-z
Copy link
Contributor

poire-z commented Jul 20, 2024

Looks like you did not touch anything related to LVFontGlyphCacheItem, so mentionning it - I see this one too often:
https://github.com/koreader/crengine/actions/runs/10022158348/job/27701636550

Running clang-tidy on crengine/src/lvfntman.cpp
2 warnings and 3 errors generated.
Error while processing /home/runner/work/crengine/crengine/crengine/src/lvfntman.cpp.
/home/runner/work/crengine/crengine/crengine/src/../include/lvfntman.h:148:25: error: 'LVFontGlyphCacheItem' does not refer to a value [clang-diagnostic-error]
        return offsetof(LVFontGlyphCacheItem, bmp) + ((bmp_width * bmp_height) * sizeof(*bmp));
                        ^
Suppressed 2 warnings (2 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
Found compiler error(s).
/home/runner/work/crengine/crengine/crengine/src/../include/lvfntman.h:124:8: note: declared here
struct LVFontGlyphCacheItem
       ^
/home/runner/work/crengine/crengine/crengine/src/../include/lvfntman.h:152:80: error: 'LVFontGlyphCacheItem' does not refer to a value [clang-diagnostic-error]
        LVFontGlyphCacheItem * item = (LVFontGlyphCacheItem *)malloc( offsetof(LVFontGlyphCacheItem, bmp)
                                                                               ^
/home/runner/work/crengine/crengine/crengine/src/../include/lvfntman.h:124:8: note: declared here
struct LVFontGlyphCacheItem
       ^
/home/runner/work/crengine/crengine/crengine/src/../include/lvfntman.h:152:102: error: invalid use of member 'bmp' in static member function [clang-diagnostic-error]
        LVFontGlyphCacheItem * item = (LVFontGlyphCacheItem *)malloc( offsetof(LVFontGlyphCacheItem, bmp)

@benoit-pierre benoit-pierre marked this pull request as draft July 20, 2024 22:08
@benoit-pierre
Copy link
Contributor Author

Let me do a pass with clang.

Copy link
Contributor

@poire-z poire-z left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok overall.
Trusting you on antiword and chmlib :)

crengine/src/epubfmt.cpp Show resolved Hide resolved
crengine/src/lvdocview.cpp Outdated Show resolved Hide resolved
crengine/src/lvdocview.cpp Outdated Show resolved Hide resolved
crengine/src/lvfntman.cpp Show resolved Hide resolved
crengine/src/lvrend.cpp Show resolved Hide resolved
Comment on lines 3853 to +3855
else if ( vertical_align_flag == LTEXT_VALIGN_MIDDLE ) {
assert(top_to_baseline != -1);
assert(baseline_to_bottom != -1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other branches assign them, or do arithmetic with them. Why only here?
(There's some sane logic, the only outer branch that don't set and use it is when LTEXT_OBJECT_IS_PAD / LTEXT_WORD_IS_PAD, which I admit is a bit strange, checking LTEXT_OBJECT, setting LTEXT_WORD, checking LTEXT_OBJECT...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: that's where the compiler detected a possible problem.

crengine/src/lvtinydom.cpp Show resolved Hide resolved
@@ -8016,6 +8013,7 @@ void ldomNode::initNodeRendMethod()
if (eoc)
break;
}
assert(elemId != -3);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK for -3 (as we use -1 and -2 for other flags).
Anyway, is this just fine putting assert when we can't make out the logic, or should I look at how this could happen and rework a logic around that?

crengine/src/lvxml.cpp Show resolved Hide resolved
crengine/src/mathml.cpp Show resolved Hide resolved
@benoit-pierre
Copy link
Contributor Author

benoit-pierre commented Jul 21, 2024

For the indentation issues: we compile with -ftabstop=4, this take care of most warnings due to mixing both tabs and spaces to indent. The remaining warnings code looks like -ftabstop=8 is assumed (which is Github default too, I guess). I can either amend to use tabs, or spaces, everywhere to fix those and the Github display issue.

@benoit-pierre
Copy link
Contributor Author

Regarding asserts: they are disabled in release mode, so good to shut up compiler warnings, detect coding/logic mistakes, possible bugs.

@poire-z
Copy link
Contributor

poire-z commented Jul 21, 2024

I can either amend to use tabs, or spaces, everywhere to fix the warning and the Github display issue.

"everywhere" meaning where there are warnings right ? :) (Keep changes minimal to avoid messing git blame).
I'd say: do as I do, conform to the spacing used by the lines in the function you don't need to touch (and if between 2 styles/solutions, chose the one needing less changes, or changing dumb lines without much logic).

@benoit-pierre
Copy link
Contributor Author

I can either amend to use tabs, or spaces, everywhere to fix the warning and the Github display issue.

"everywhere" meaning where there are warnings right ? :) (Keep changes minimal to avoid messing git blame). I'd say: do as I do, conform to the spacing used by the lines in the function you don't need to touch (and if between 2 styles/solutions, chose the one needing less changes, or changing dumb lines without much logic).

Yes, only to fix the warnings, minimal changes.

@benoit-pierre
Copy link
Contributor Author

And regarding the linter (cppcheck / clang-tidy) warnings: I don't think the way they are currently run is that useful. I've added support locally to the build system, taking advantage of the fact that both linters can use the compilation database generated by cmake, and I'm not getting the same warnings as on GA.

See integration here.

I'm not sure if it's because locally I make sure the crsetup.h file generated by the build system is used, and all the necessary headers (including dependencies) are available.

Maybe we should revisit the crsetup.h situation. Currently, they are 3 defines set by cmake at configure time: _DEBUG, DISABLE_CLOEXEC & HAVE_OFF64_T.

And those are used in crengine headers, so currently part of the public API.

_DEBUG

lvarray.h:

    /// copies range to beginning of array
    void trim( int pos, int count, int reserved )
    {
#if defined(_DEBUG) && !defined(ANDROID)
        if ( pos<0 || count<=0 || pos+count > _count )
            throw;
#endif
[…]
    /// removes several items from vector
    void erase( int pos, int count )
    {
#if defined(_DEBUG) && !defined(ANDROID)
        if ( pos<0 || count<=0 || pos+count > _count )
            throw;
#endif
[…]

We could change this code to only detect coding mistakes:

    /// copies range to beginning of array
    void trim( int pos, int count, int reserved )
    {
        assert( pos >= 0 && count > 0 && pos+count <= _count );
[…]
    /// removes several items from vector
    void erase( int pos, int count )
    {
        assert( pos >= 0 && count > 0 && pos+count <= _count );
[…]

Which would please cppcheck:

warning: Rethrowing current exception with 'throw;', it seems there is no current exception to rethrow. If there is no current exception this calls std::terminate().

lvtinydom.h:

#ifdef _DEBUG
#if BUILD_LITE!=1
    ///debug method, for DOM tree consistency check, returns false if failed
    bool checkConsistency( bool requirePersistent );
#endif
#endif

All calls to checkConsistency are commented out, so we can just comment the declaration too.

lvstring.h:

#ifdef _DEBUG
#include <stdio.h>
class DumpFile
{
[…]
};
#endif

No change to other class/struct layouts, and DumpFile is only used in wolutil.cpp (which we don't compile anymore). We can comment that part.

And then move _DEBUG out of crsetup.h (add it to crengine's private compilations flags).

DISABLE_CLOEXEC & HAVE_OFF64_T

That part is more thorny:

/// Streams.
#cmakedefine DISABLE_CLOEXEC                      1
#cmakedefine HAVE_OFF64_T                         1
#ifdef HAVE_OFF64_T
# define HAVE_STAT64                         1
# define _LARGEFILE64_SOURCE                 1
#endif

DISABLE_CLOEXEC is used in lvplatform.h, included by many, but it looks like the impact is limited to source files, so move it to the private compilation flags.

HAVE_OFF64_T is not used anywhere else. HAVE_STAT64 is only used in lvstream.cpp, but I don't know if _LARGEFILE64_SOURCE can change the layout of some classes/structs (in lvstream.h).

Assuming we can remove those #cmakedefines …, to make crsetup.h's contents static, we can replace the one in crengine, and use it for clang-tidy/cppcheck and simplify a couple of things.

@benoit-pierre
Copy link
Contributor Author

benoit-pierre commented Jul 21, 2024

Anyway, I did another pass with clang, other targets. Except for the aforementioned lvref warnings, the only compiler warnings left are clang grumbling about VLAs.

cppcheck is happy (locally).

clang-tidy still complains a lot (locally, again). Those warnings are not obvious (and a number of them may be false positives related to lvref, again).

@benoit-pierre
Copy link
Contributor Author

And clang-tidy takes forever… There's some cmake support for running clang-tidy automatically as part of the compilation, but without some sort of cache, that would be painful.

@benoit-pierre benoit-pierre marked this pull request as ready for review July 21, 2024 22:51
@@ -1848,7 +1848,7 @@ class LVFormatter {
int tabIndex = -1;
#if (USE_FRIBIDI==1)
FriBidiLevel lastBidiLevel = 0;
FriBidiLevel newBidiLevel;
FriBidiLevel newBidiLevel = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No "value assigned is never used" warning with that?

Comment on lines -14374 to +14373
lString32 ldomXRange::getRangeText( lChar32 blockDelimiter, int maxTextLen, lChar32 imageReplacement, LVArray<ldomNode*> * imageNodes )
lString32 ldomXRange::getRangeText( lChar32 blockDelimiter, lChar32 imageReplacement, LVArray<ldomNode*> * imageNodes )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some stuff in cre.cpp provide maxTextLen=8192 (which ok, is not used), so don't forget to update it.

crengine/src/lvxml.cpp Show resolved Hide resolved
crengine/src/mathml.cpp Outdated Show resolved Hide resolved
crengine/src/odtfmt.cpp Show resolved Hide resolved
@poire-z
Copy link
Contributor

poire-z commented Jul 21, 2024

No real thought / opinion about #579 (comment) , so go ahead as you please :)
Btw, what about the LVFontGlyphCacheItem warning I mentionned in 2nd post?

@benoit-pierre
Copy link
Contributor Author

No real thought / opinion about #579 (comment) , so go ahead as you please :) Btw, what about the LVFontGlyphCacheItem warning I mentionned in 2nd post?

Re-read that comment ;)

The way the linters are run on GA does not match the actual build configuration. I get no such warning when running with koreader/koreader-base@941fbbf locally (Arch Linux, clang-tidy 18.1.8) or in docker (using koreader/kobase:0.3.4-20.04, clang-tidy 10.0.0).

```
warning: Rethrowing current exception with 'throw;', it seems there is no current
exception to rethrow. If there is no current exception this calls std::terminate().
```
Comment out unused & problematic code:
```
crengine/include/lvref.h:395:16: warning: Reference to temporary returned. [returnTempReference]
   return LVRef(NULL);
               ^
crengine/include/lvref.h:396:15: warning: Reference to temporary returned. [returnTempReference]
  return LVRef( new T( *_ptr ) );
```
```
warning: Value stored to 'pDiag' is never read [clang-analyzer-deadcode.DeadStores]
```
```
warning: Rethrowing current exception with 'throw;', it seems there is no current
exception to rethrow. If there is no current exception this calls std::terminate().
```
@poire-z
Copy link
Contributor

poire-z commented Jul 22, 2024

The way the linters are run on GA does not match the actual build configuration.

I understand. I think they currently pick a few random combinations of #define, and see how they go. The fact is that in some/all combinations of there, the LVFontGlyphCacheItem is one (with 1 or 2 others) we always get, so there must be something odd.
Even if you can't reproduce it, do you understand what is the complain in the output on GA?

@benoit-pierre
Copy link
Contributor Author

Look at all those Error while processing and unknown type name 'uint64_t' errors: parsing C/C++ is famously hard (context sensitive), and if the configuration is borked and some basic types are not recognized, then things can snowball from there.

@benoit-pierre
Copy link
Contributor Author

Locally, from the crengine checkout:

▹ clang-tidy crengine/src/lvfntman.cpp -- -Icrengine/include
3 errors generated.
Error while processing […]/base/thirdparty/kpvcrlib/crengine/crengine/src/lvfntman.cpp.
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/lvfntman.h:148:25: error: 'LVFontGlyphCacheItem' does not refer to a value [clang-diagnostic-error]
  148 |         return offsetof(LVFontGlyphCacheItem, bmp) + ((bmp_width * bmp_height) * sizeof(*bmp));
      |                         ^
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/lvfntman.h:124:8: note: declared here
  124 | struct LVFontGlyphCacheItem
      |        ^
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/lvfntman.h:152:80: error: 'LVFontGlyphCacheItem' does not refer to a value [clang-diagnostic-error]
  152 |         LVFontGlyphCacheItem * item = (LVFontGlyphCacheItem *)malloc( offsetof(LVFontGlyphCacheItem, bmp)
      |                                                                                ^
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/lvfntman.h:124:8: note: declared here
  124 | struct LVFontGlyphCacheItem
      |        ^
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/lvfntman.h:152:102: error: invalid use of member 'bmp' in static member function [clang-diagnostic-error]
  152 |         LVFontGlyphCacheItem * item = (LVFontGlyphCacheItem *)malloc( offsetof(LVFontGlyphCacheItem, bmp)
      |                                                                                                      ^~~
Found compiler error(s).

▹ clang-tidy crengine/src/lvfntman.cpp -- -DLINUX -Icrengine/include
1 error generated.
Error while processing […]/base/thirdparty/kpvcrlib/crengine/crengine/src/lvfntman.cpp.
[…]/base/thirdparty/kpvcrlib/crengine/crengine/src/../include/textlang.h:5:10: error: 'hb.h' file not found [clang-diagnostic-error]
    5 | #include <hb.h>
      |          ^~~~~~
Found compiler error(s).

It's the config.

This was referenced Jul 22, 2024
@benoit-pierre benoit-pierre marked this pull request as draft July 24, 2024 01:04
@poire-z
Copy link
Contributor

poire-z commented Jul 27, 2024

Good to go? Or still working on it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants