[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#780718: return in ?:-operator with function calls is incorrectly optimized



On Thu, Mar 19, 2015 at 10:40:32PM +0100, Matthias Klose wrote:
> On 03/18/2015 11:39 AM, David Kalnischkies wrote:
> > Attached is as far as I got in terms of a testcase. Still depends on
> > libapt as if I make the method directly available everything is fine…
> 
> would it be possible to have a test case which doesn't link the library, maybe
> by including all relevant files so that we have a single translation unit?

meehh, figured out now what is missing to get this to reproduce in
a smaller case which makes this a rather big mistake on my side:

The VectorizeString function has the 'const' attribute applied which is
documented as not to be used if pointers are involved, but the char&
parameter is a char* in disguise… (in a perfect world the & wouldn't
be there). Attached the 'fixed' code to reproduce this just in case.
[going with 'pure' for the time being now as good enough, it isn't
 called as much as it used to be anyway - if I remember right]

Its a bit misfortune that g++ isn't indicating this misuse (and the
result is a bit strange, too), but that is at most a wishlist I guess,
so feel free to close if you want.


Best regards

David Kalnischkies
// g++ -Wall -Wextra -O0 -lapt-pkg /tmp/test.cc -o /tmp/test && /tmp/test
// g++ -Wall -Wextra -O2 -lapt-pkg /tmp/test.cc -o /tmp/test && /tmp/test
#include <string>
#include <map>
#include <vector>
#include <iostream>

std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) __attribute__((const));

std::vector<std::string> VectorizeString(std::string const &haystack, char const &split)
{
   std::vector<std::string> exploded;
   if (haystack.empty() == true)
      return exploded;
   std::string::const_iterator start = haystack.begin();
   std::string::const_iterator end = start;
   do {
      for (; end != haystack.end() && *end != split; ++end);
      exploded.push_back(std::string(start, end));
      start = end + 1;
   } while (end != haystack.end() && (++end) != haystack.end());
   return exploded;
}

std::vector<std::string> getDefaultVector() {
	std::vector<std::string> r; // broken g++-4.x & g++-5
	//static std::vector<std::string> r; // just g++-5
	return r;
}

void parseOptions(std::map<std::string, std::string> const &Options, std::string const &field) {
	std::map<std::string, std::string>::const_iterator arch = Options.find(field);
	std::vector<std::string> Archs =
		(arch != Options.end()) ? VectorizeString(arch->second, ',') :
		getDefaultVector(); // <- never called, but method content effects result

	for (std::vector<std::string>::const_iterator a = Archs.begin(); a != Archs.end(); ++a)
		std::cout << *a << std::endl;
}

int main() {
	std::map<std::string, std::string> Options;
	Options["a"] = "amd64,i386,armel";
	parseOptions(Options, "a");

	return 0;
}

Attachment: signature.asc
Description: Digital signature


Reply to: