⬆️ ⬇️

PVS-Studio now supports C ++ / CLI

PVS-Studio, C ++ / CLI

Support for projects written in C ++ / CLI is not a priority in PVS-Studio. There are quite a few such projects, but nevertheless from time to time we come across them. Microsoft currently has no plans to stop supporting the C ++ / CLI language, so we decided to support this type of language.



C ++ / CLI support



Wikipedia: C ++ / CLI - C ++ programming language binding to Microsoft .NET programming environment. It integrates the C ++ ISO standard with the Unified Type System (UTS), considered as part of the Common Language Infrastructure (Common Language Infrastructure, CLI). It supports both the source level and the interoperability of executables compiled from native and managed C ++. C ++ / CLI is a further development of C ++.



We implemented C ++ / CLI support in PVS-Studio at a level sufficient for testing most projects. However, we didn’t have enough projects to test and some language constructs may be processed incorrectly or will produce obviously false positives. It's hard to keep track of everything. If you have any problems with checking your projects, please let us know.



This article can be finished, but it is not interesting. Therefore, we checked a small project SlimDX about what and describe below.

')

Slimdx



Wikipedia: SlimDX is an open source API to DirectX programming under .NET. SlimDX can be used for any language under the .NET runtime (due to the CLR). SlimDX can be used to develop multimedia and interactive applications (eg games). It makes it possible to use the graphical hardware.



Official site: http://slimdx.org/



The check was carried out with the help of the PVS-Studio code analyzer. Since the project is small and represents a wrapper over another library, there were very few suspicious places. However, they are enough to write about them.



Test results



Below are the code snippets that seemed to me wrong.



Fragment N1

ContainmentType BoundingBox::Contains( BoundingBox box, BoundingSphere sphere ) { .... if( box.Minimum.X + radius <= sphere.Center.X && sphere.Center.X <= box.Maximum.X - radius && box.Maximum.X - box.Minimum.X > radius && <<<=== box.Minimum.Y + radius <= sphere.Center.Y && sphere.Center.Y <= box.Maximum.Y - radius && box.Maximum.Y - box.Minimum.Y > radius && box.Minimum.Z + radius <= sphere.Center.Z && sphere.Center.Z <= box.Maximum.Z - radius && box.Maximum.X - box.Minimum.X > radius) <<<=== return ContainmentType::Contains; .... } 


PVS-Studio warning: V501 There are identical sub-expressions 'box.Maximum.X - box.Minimum.X> radius' operator. boundingbox.cpp 94



Most likely this code was written using Copy-Paste and forgot to make changes in the last line. At the end of the expression should be written "box.Maximum.Z - box.Minimum.Z> radius".



Fragment N2

 typedef struct DIJOYSTATE2 { .... LONG rglSlider[2]; .... LONG rglVSlider[2]; .... LONG rglASlider[2]; .... LONG rglFSlider[2]; .... } DIJOYSTATE2, *LPDIJOYSTATE2; void JoystickState::AssignState(const DIJOYSTATE2 &joystate) { .... for( int i = 0; i < 2; i++ ) { sliders[i] = joystate.rglSlider[i]; asliders[i] = joystate.rglASlider[i]; vsliders[i] = joystate.rglVSlider[i]; fsliders[i] = joystate.rglVSlider[i]; } .... } 


PVS-Studio warning: V525 The code containing the collection of similar blocks. Check items 'rglSlider', 'rglASlider', 'rglVSlider', 'rglVSlider' in lines 93, 94, 95, 96. joystickstate.cpp 93



I think this code contains a typo. The last line probably should have used the rglFSlider array:

 sliders[i] = joystate.rglSlider[i]; asliders[i] = joystate.rglASlider[i]; vsliders[i] = joystate.rglVSlider[i]; fsliders[i] = joystate.rglFSlider[i]; 


Fragment N3

 array<SoundEffectResult>^ SecondarySoundBuffer::SetEffects( array<Guid>^ effects ) { DWORD count = effects->Length; .... if( effects != nullptr && count > 0 ) .... } 


PVS-Studio warning: V595 The 'effects' pointer was used before it was verified against nullptr. Check lines: 66, 73. secondarysoundbuffer.cpp 66



At the beginning, the 'effects' pointer is dereferenced. Then, in the code below, it is checked for equality to zero.



Fragment N4



There is a 'TVariable' class that contains virtual functions:

 template<typename IBaseInterface> struct TVariable : public IBaseInterface { virtual BOOL IsValid() { .... } .... }; 


The class SMember is inherited from this class. Note that zeros are written to the fields of this class using the ZeroMemory () function.

 struct SMember : public TVariable<TMember<ID3DX11EffectVariable> > { }; CEffectVectorOwner<SMember> m_pMemberInterfaces; ZeroMemory HRESULT CEffect::CopyMemberInterfaces(....) { .... ZeroMemory( &m_pMemberInterfaces[i], sizeof(SMember) * ( Members - i ) ); .... } 


PVS-Studio warning: V598 The 'memset' function is used to make it clear the fields of the 'SMember' class. Virtual method table will be maintained by this. effectnonruntime.cpp 1739



Since there are virtual functions, the SMember class contains a pointer to a table of virtual methods. This pointer will be corrupted when the ZeroMemory () function is called.



Similarly:

Fragment N5

 #pragma warning(disable: 4369) public enum class WaveFormatTag : System::Int32 { Pcm = WAVE_FORMAT_PCM, AdPcm = WAVE_FORMAT_ADPCM, IeeeFloat = WAVE_FORMAT_IEEE_FLOAT, MpegLayer3 = WAVE_FORMAT_MPEGLAYER3, DolbyAC3Spdif = WAVE_FORMAT_DOLBY_AC3_SPDIF, WMAudio2 = WAVE_FORMAT_WMAUDIO2, WMAudio3 = WAVE_FORMAT_WMAUDIO3, WmaSpdif = WAVE_FORMAT_WMASPDIF, Extensible = WAVE_FORMAT_EXTENSIBLE, }; #pragma warning(default: 4369) 


PVS-Studio warning: V665 Possibly, the usage of #pragma warning (default: X) 'is incorrect in this context. The '#pragma warning (push / pop)' should be used instead. Check lines: 1089, 1102. enums.h 1102



Incorrect compiler warnings suppressed. At the end, the default value is restored. More correctly at the beginning to save the state of the settings, and then restore. This is not a serious mistake. However, for libraries it is important not to spoil the alert level settings in user projects. The correct way to suppress warnings is described in the V665 warning description .



There are several similar shortcomings in the header file "enums.h". Line numbers: 224, 267, 346.



Conclusion



I admit that the first article about checking the C ++ / CLI project turned out to be boring and brief. The first pancake is lumpy. I hope in the future it will be possible to check out some larger and more interesting project.



I suggest to download and test your C ++ / CLI projects using PVS-Studio . We will be happy to receive your feedback and comments.



This article is in English.



If you want to share this article with an English-speaking audience, then please use the link to the translation: Andrey Karpov. C ++ / CLI Now Supported in PVS-Studio .



Read the article and have a question?
Often our articles are asked the same questions. We collected the answers to them here: Answers to questions from readers of articles about PVS-Studio and CppCat, version 2014 . Please review the list.

Source: https://habr.com/ru/post/221721/



All Articles